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

Revision 1545, 12.5 KB checked in by wmerlotto, 14 years ago (diff)

Ticket #693 - Incrementado a sincronizacao de contatos, integracao com maven e codigo de autenticacao no LDAP.

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