source: contrib/psync/src/main/java/br/com/prognus/psync/items/dao/PIMEntityDAO.java @ 1009

Revision 1009, 11.3 KB checked in by wmerlotto, 15 years ago (diff)

Ticket #554 - Commit da versão inicial do psync.

Line 
1/**
2 * This class implements methods to access PIM data in a data store.
3 * @author Diorgenes Felipe Grzesiuk <diorgenes@prognus.com.br>
4 * @copyright Copyright 2007-2008 Prognus
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Foobar; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19package br.com.prognus.psync.items.dao;
20
21import java.sql.Connection;
22import java.sql.PreparedStatement;
23import java.sql.ResultSet;
24import java.sql.Timestamp;
25import java.util.Enumeration;
26import java.util.Iterator;
27import java.util.List;
28
29import javax.naming.NamingException;
30import javax.sql.DataSource;
31
32import br.com.prognus.psync.exception.PIMDBAccessException;
33import br.com.prognus.psync.util.Def;
34
35import com.funambol.common.pim.common.Property;
36import com.funambol.framework.logging.FunambolLogger;
37import com.funambol.framework.logging.FunambolLoggerFactory;
38import com.funambol.framework.tools.DBTools;
39import com.funambol.framework.tools.DataSourceTools;
40import com.novell.ldap.LDAPAttribute;
41import com.novell.ldap.LDAPAttributeSet;
42import com.novell.ldap.LDAPConnection;
43import com.novell.ldap.LDAPEntry;
44import com.novell.ldap.LDAPException;
45import com.novell.ldap.LDAPSearchResults;
46import com.novell.ldap.util.Base64;
47
48public abstract class PIMEntityDAO {
49
50        // ------------------------------------------------------------ Private data
51
52        protected static final FunambolLogger log = FunambolLoggerFactory
53                        .getLogger(Def.LOGGER_NAME);
54
55        protected String jndiDataSourceName;
56
57        protected DataSource dataSource = null;
58
59        // -------------------------------------------------------------- Properties
60
61        protected String userId;
62
63        public String getUserId() {
64                return userId;
65        }
66
67        // ------------------------------------------------------------ Constructors
68
69        /**
70         * Creates a new instance of PIMEntityDAO, ready to be linked to a given
71         * DataSource.
72         *
73         * @param jndiDataSourceName
74         *            the jndiname of the datasource to use
75         * @param userId
76         *            corresponding to the "userid" field of the fun_pim_contact
77         *            table
78         * @throws IllegalArgumentException
79         *             if there are errors looking up the dataSource with the given
80         *             jndiDataSourceName
81         */
82        public PIMEntityDAO(String jndiDataSourceName, String userId) {
83
84                Connection con = null;
85                PreparedStatement ps = null;
86
87                try {
88                        this.dataSource = DataSourceTools
89                                        .lookupDataSource(jndiDataSourceName);
90                } catch (NamingException ex) {
91                        throw new IllegalArgumentException("Error looking up datasource: "
92                                        + jndiDataSourceName, ex);
93                }
94
95                try {
96                        con = getDataSource().getConnection();
97
98                        PreparedStatement ldap_server = con
99                                        .prepareStatement("select config_value from phpgw_config WHERE config_name = 'ldap_host' AND config_app = 'phpgwapi'");
100                        ResultSet rs1 = ldap_server.executeQuery();
101
102                        PreparedStatement ldap_dc = con
103                                        .prepareStatement("select config_value from phpgw_config WHERE config_name = 'ldap_context' AND config_app = 'phpgwapi'");
104                        ResultSet rs2 = ldap_dc.executeQuery();
105
106                        rs1.next();
107                        rs2.next();
108
109                        String server = rs1.getString(1);
110                        String dc = rs2.getString(1);
111
112                        this.jndiDataSourceName = jndiDataSourceName;
113                        this.userId = LdapUID(server, dc, userId);
114
115                } catch (Exception e) {
116                        throw new IllegalArgumentException("Error UID ldap", e);
117                } finally {
118                        DBTools.close(con, ps, null);
119                }
120
121        }
122
123        // -----------------------------------------------------------Public methods
124
125        protected String LdapUID(String server, String dc, String user)
126                        throws Exception {
127
128                LDAPConnection ldap = new LDAPConnection();
129                String searchAttrs[] = { "uidNumber" };
130                String id_owner = null;
131
132                try {
133
134                        ldap.connect(server, 389);
135                        LDAPSearchResults searchResults = ldap.search(dc,
136                                        LDAPConnection.SCOPE_SUB, "(uid=" + user + ")",
137                                        searchAttrs, false);
138
139                        while (searchResults.hasMore()) {
140
141                                LDAPEntry nextEntry = null;
142                                try {
143                                        nextEntry = searchResults.next();
144                                } catch (LDAPException e) {
145                                        if (e.getResultCode() == LDAPException.LDAP_TIMEOUT
146                                                        || e.getResultCode() == LDAPException.CONNECT_ERROR)
147                                                break;
148                                        else
149                                                continue;
150                                }
151                                LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
152                                Iterator allAttributes = attributeSet.iterator();
153
154                                while (allAttributes.hasNext()) {
155
156                                        LDAPAttribute attribute = (LDAPAttribute) allAttributes
157                                                        .next();
158                                        String attributeName = attribute.getName();
159                                        Enumeration allValues = attribute.getStringValues();
160
161                                        if (allValues != null) {
162
163                                                while (allValues.hasMoreElements()) {
164
165                                                        String Value = (String) allValues.nextElement();
166
167                                                        if (Base64.isLDIFSafe(Value)) {
168                                                        } else {
169                                                                Value = Base64.encode(Value.getBytes());
170                                                        }
171
172                                                        if (attributeName.equalsIgnoreCase("uidNumber")) {
173                                                                id_owner = Value;
174                                                                break;
175                                                        }
176
177                                                }
178                                        }
179                                }
180                        }
181
182                        ldap.disconnect();
183
184                        if (id_owner == null) {
185                                throw new LDAPException();
186                        }
187
188                } catch (LDAPException e) {
189                        log.info("Error while connecting and binding to LDAP: "
190                                        + e.toString());
191                }
192
193                return id_owner;
194        }
195
196        /**
197         * Looks up the data source, making some guess attempts based on
198         * jndiDataSourceName.
199         *
200         * @throws Exception
201         */
202        protected DataSource getDataSource() throws Exception {
203                return dataSource;
204        }
205
206        public abstract List getAllItems() throws PIMDBAccessException;
207
208        public abstract void removeItem(String uid) throws PIMDBAccessException;
209
210        public abstract void removeAllItems() throws PIMDBAccessException;
211
212        public abstract char getItemState(String uid, Timestamp since)
213                        throws PIMDBAccessException;
214
215        /**
216         * Retrieves the UID list of the new items belonging to the user filtered
217         * according to the given time interval.
218         *
219         * @param since
220         *            the earliest allowed last-update Timestamp
221         * @param to
222         *            the latest allowed last-update Timestamp
223         * @throws PIMDBAccessException
224         * @return a List of UIDs (as String objects)
225         */
226        public List getNewItems(Timestamp since, Timestamp to)
227                        throws PIMDBAccessException {
228
229                log.info("\n\n==>DAO start getNewItems");
230                return getItemsHavingStatus(since, to, 'N');
231        }
232
233        /**
234         * Retrieves the UID list of the deleted items belonging to the user
235         * filtered according to the given time interval.
236         *
237         * @param since
238         *            the earliest allowed last-update Timestamp
239         * @param to
240         *            the latest allowed last-update Timestamp
241         * @throws PIMDBAccessException
242         * @return a List of UIDs (as String objects)
243         */
244        public List getDeletedItems(Timestamp since, Timestamp to)
245                        throws PIMDBAccessException {
246
247                log.info("\n\n==>DAO start getDeletedItems");
248                return getItemsHavingStatus(since, to, 'D');
249        }
250
251        /**
252         * Retrieves the UID list of the updated items belonging to the user
253         * filtered according to the given time interval.
254         *
255         * @param since
256         *            the earliest allowed last-update Timestamp
257         * @param to
258         *            the latest allowed last-update Timestamp
259         * @throws PIMDBAccessException
260         * @return a List of UIDs (as String objects)
261         */
262        public List getUpdatedItems(Timestamp since, Timestamp to)
263                        throws PIMDBAccessException {
264
265                log.info("\n\n==>DAO start getUpdatedItems");
266                return getItemsHavingStatus(since, to, 'U');
267        }
268
269        // ---------------------------------------------------------- Private
270        // methods
271
272        /**
273         * Retrieves the UID list of the items belonging to the user filtered
274         * according to the given time interval and status.
275         *
276         * @param since
277         *            the earliest allowed last-update Timestamp
278         * @param to
279         *            the latest allowed last-update Timestamp
280         * @param status
281         *            'D' for deleted items, 'N' for new items, 'U' for updated
282         *            items
283         * @throws PIMDBAccessException
284         * @return a List of UIDs (as String objects)
285         */
286        protected abstract List getItemsHavingStatus(Timestamp since, Timestamp to,
287                        char status) throws PIMDBAccessException;
288
289        /**
290         * Checks (safely) whether the property is unset.
291         *
292         * @param property
293         *            may be null
294         * @return false only if the property value is a non-null, but possibly
295         *         empty (""), string
296         *
297         * @see PIMEntityDAO#stringFrom(Property)
298         */
299        protected static boolean isNullProperty(Property property) {
300
301                return (property == null || property.getPropertyValueAsString() == null);
302        }
303
304        /**
305         * Checks (safely) whether the property is unset or set to an empty string.
306         *
307         * @param property
308         *            may be null
309         * @return false only if the property value is a non-null non-empty string
310         *
311         * @see PIMEntityDAO#stringFrom(Property, boolean)
312         */
313        protected static boolean isEmptyProperty(Property property) {
314
315                if (property == null) {
316                        return true;
317                }
318                String string = property.getPropertyValueAsString();
319                if (string == null || string.length() == 0) {
320                        return true;
321                }
322                return false;
323        }
324
325        /**
326         * Extract a string from a property in a safe way. An empty string ("") is
327         * considered as an acceptable value for the property: in such a case, an
328         * empty String object will be returned.
329         *
330         * @param property
331         *            may be null
332         * @return if existing, the property value will be returned as a String
333         *         object
334         */
335        protected static String stringFrom(Property property) {
336
337                if (property == null) {
338                        return null;
339                }
340                return property.getPropertyValueAsString();
341        }
342
343        /**
344         * Extract a string from a property in a safe way. This method is not
345         * currently used, but it could be useful in the future for determining the
346         * behaviour of the connector when dealing with empty properties. A field
347         * whose value is extracted with stringFrom(..., true) will not be updated
348         * in case its value is set to ""; a field whose value is extracted with
349         * stringFrom(..., false) will be considered as explicitly kept blank if its
350         * value is "". This means that single field deletions can be made tunable.
351         *
352         * @param property
353         *            may be null
354         * @param emptyImpliesNull
355         *            if true, an empty string ("") will be treated as if it were
356         *            null; otherwise, in such a case an empty String object will be
357         *            returned
358         *
359         * @return if existing (and not empty if emptyImpliesNull is true), the
360         *         property value will be returned as a String object
361         */
362        protected static String stringFrom(Property property,
363                        boolean emptyImpliesNull) {
364
365                if (property == null) {
366                        return null;
367                }
368
369                String string = property.getPropertyValueAsString();
370                if (string == null || !emptyImpliesNull) {
371                        return string;
372                }
373
374                if (string.length() == 0) {
375                        return null;
376                }
377                return string;
378        }
379
380        /**
381         * Gets a substring in a safe way.
382         *
383         * @param string
384         *            may be null or longer than maxLength
385         * @param maxLength
386         * @return null if the string is null, a truncated substring of string
387         *         otherwise
388         */
389        protected static String truncate(String string, int maxLength) {
390                if (string == null || string.length() <= maxLength) {
391                        return string;
392                }
393                return string.substring(0, maxLength);
394        }
395}
Note: See TracBrowser for help on using the repository browser.