KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > dav > server > managers > HarmoniseSearchManager


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19
20 package org.openharmonise.dav.server.managers;
21
22 import java.net.URL JavaDoc;
23 import java.text.*;
24 import java.util.*;
25 import java.util.logging.*;
26
27 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
28
29 import org.openharmonise.commons.dsi.*;
30 import org.openharmonise.commons.xml.namespace.NamespaceType;
31 import org.openharmonise.dav.server.utils.*;
32 import org.openharmonise.rm.*;
33 import org.openharmonise.rm.dsi.DataStoreInterfaceFactory;
34 import org.openharmonise.rm.factory.HarmoniseFactoryException;
35 import org.openharmonise.rm.metadata.*;
36 import org.openharmonise.rm.resources.*;
37 import org.openharmonise.rm.resources.content.TextResource;
38 import org.openharmonise.rm.resources.metadata.properties.*;
39 import org.openharmonise.rm.resources.metadata.properties.ranges.DateRange;
40 import org.openharmonise.rm.search.Search;
41 import org.w3c.dom.Element JavaDoc;
42
43 import com.ibm.webdav.*;
44 import com.ibm.webdav.basicsearch.BasicSearchRequest;
45 import com.ibm.webdav.impl.*;
46
47 /**
48  * This class handles the implementation of the DASL functionality for the Harmonise
49  * repository.
50  *
51  * @author Michael Bell
52  * @version $Revision: 1.2 $
53  *
54  */

55 public class HarmoniseSearchManager implements SearchManager {
56     public static final String JavaDoc W3C_XMLSCHEMA_URI =
57         "http://www.w3.org/2001/XMLSchema";
58     private AbstractDataStoreInterface m_dsi = null;
59     
60     private static final Logger m_logger = Logger.getLogger(HarmoniseSearchManager.class.getName());;
61
62     public HarmoniseSearchManager() {
63     }
64
65     public void initialize() {
66         
67
68         try {
69             this.m_dsi = DataStoreInterfaceFactory.getDataStoreInterface();
70         } catch (Exception JavaDoc e) {
71             throw new RuntimeException JavaDoc("Datastore interface not started properly.");
72         }
73     }
74
75     public SearchSchema getSearchSchema(SearchRequest searchReq)
76         throws WebDAVException {
77         SearchSchema schema = null;
78
79         try {
80             schema = searchReq.getSearchSchema();
81
82             try {
83                 org.w3c.dom.Document JavaDoc document =
84                     DocumentBuilderFactory
85                         .newInstance()
86                         .newDocumentBuilder()
87                         .newDocument();
88
89                 Element JavaDoc contentLength =
90                     document.createElementNS(
91                         NamespaceType.DAV.getURI(),
92                         "contentlength");
93                 contentLength.setPrefix(NamespaceType.DAV.getPrefix());
94
95                 Element JavaDoc intEl =
96                     document.createElementNS(
97                         NamespaceType.XML_SCHEMA.getURI(),
98                         "integer");
99                 intEl.setPrefix(NamespaceType.XML_SCHEMA.getPrefix());
100
101                 Element JavaDoc resourceType =
102                     document.createElementNS(
103                         NamespaceType.DAV.getURI(),
104                         "resourcetype");
105                 resourceType.setPrefix(NamespaceType.DAV.getPrefix());
106
107                 Element JavaDoc stringEl =
108                     document.createElementNS(
109                         NamespaceType.XML_SCHEMA.getURI(),
110                         "string");
111                 stringEl.setPrefix(NamespaceType.XML_SCHEMA.getPrefix());
112
113                 Element JavaDoc lastModifiedDate =
114                     document.createElementNS(
115                         NamespaceType.DAV.getURI(),
116                         "getlastmodified");
117                 lastModifiedDate.setPrefix(NamespaceType.DAV.getPrefix());
118
119                 Element JavaDoc dateEl =
120                     document.createElementNS(
121                         NamespaceType.XML_SCHEMA.getURI(),
122                         "date");
123                 dateEl.setPrefix(NamespaceType.XML_SCHEMA.getPrefix());
124
125                 Element JavaDoc contentType =
126                     document.createElementNS(
127                         NamespaceType.DAV.getURI(),
128                         "getcontenttype");
129                 contentType.setPrefix(NamespaceType.DAV.getPrefix());
130
131                 schema.addPropertyDescription(
132                     contentLength,
133                     intEl,
134                     false,
135                     true,
136                     false);
137
138                 schema.addPropertyDescription(
139                     resourceType,
140                     stringEl,
141                     false,
142                     true,
143                     false);
144
145                 schema.addPropertyDescription(
146                     lastModifiedDate,
147                     dateEl,
148                     false,
149                     true,
150                     true);
151
152                 schema.addPropertyDescription(
153                     contentType,
154                     stringEl,
155                     false,
156                     true,
157                     true);
158             } catch (Exception JavaDoc e) {
159                 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
160             }
161
162             schema.addAnyOtherPropertyDescription(true, true, true);
163         } catch (Exception JavaDoc e) {
164             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
165             throw new WebDAVException(
166                 WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
167                 "Had trouble getting schema");
168         }
169
170         return schema;
171     }
172
173     /**
174      * Get the results of search
175      *
176      * @return a Vector of Resources (ResourceImpl or CollectionImpl)
177      * @exception com.ibm.webdav.WebDAVException
178      */

179     public Vector executeSearch(SearchRequest searchReq, ResourceImpl resource)
180         throws WebDAVException {
181         
182         Vector resources = new Vector();
183
184         try {
185             AbstractChildObject child = getWorkflowObject(resource);
186
187             AbstractParentObject parent = null;
188
189             if (child != null) {
190                 if (child instanceof AbstractParentObject) {
191                     parent = (AbstractParentObject) child;
192                 } else {
193                     parent = child.getRealParent();
194                 }
195             }
196
197             Vector selectProps = searchReq.getSelectProperties();
198             SearchCondition condition = searchReq.getCondition();
199
200             //this will either be a absolute ref or a ref relative to the request URI
201
String JavaDoc scope_href = searchReq.getScopeURI();
202
203             if ((scope_href != null) && (scope_href.length() > 0)) {
204                 if (scope_href.startsWith("http")) {
205                     parent = null;
206                 } else if (scope_href.startsWith("ftp")) {
207                     parent = null;
208                 } else if (scope_href.startsWith("/")) {
209
210                     AbstractChildObject scope_wflw =
211                         HarmoniseNameResolver.getObjectFromURL(m_dsi, scope_href);
212
213                     if (scope_wflw instanceof AbstractParentObject) {
214                         parent = (AbstractParentObject) scope_wflw;
215                     } else {
216                         parent = scope_wflw.getRealParent();
217                     }
218                 } else {
219                     StringBuffer JavaDoc sPath = new StringBuffer JavaDoc();
220                     sPath.append(resource.getURL().getPath());
221
222                     if (sPath.toString().endsWith("/") == false) {
223                         sPath.append("/");
224                     }
225
226                     sPath.append(scope_href);
227
228                     AbstractChildObject scope_wflw =
229                         HarmoniseNameResolver.getObjectFromURL(
230                             m_dsi,
231                             sPath.toString());
232
233                     if (scope_wflw instanceof AbstractParentObject) {
234                         parent = (AbstractParentObject) scope_wflw;
235                     } else {
236                         parent = scope_wflw.getRealParent();
237                     }
238                 }
239             }
240
241             //if scope uri didn't result in a valid sec throw bad request
242
if (parent == null) {
243                 throw new WebDAVException(
244                     WebDAVStatus.SC_BAD_REQUEST,
245                     "Invalid scope");
246             }
247
248             int scope_depth = searchReq.getScopeDepth();
249
250             
251             Vector allChildren = new Vector();
252
253             List childTypes = parent.getChildClassNames();
254
255             Iterator iter = childTypes.iterator();
256
257             boolean bFirstTime = true;
258
259             while (iter.hasNext()) {
260                 Search oh_search = new Search(this.m_dsi);
261                 oh_search.cacheResults(false);
262
263                 int nLimit = searchReq.getResultLimit();
264
265                 if (nLimit > 0) {
266                     oh_search.setResultSize(nLimit);
267                 }
268
269                 oh_search.addConditionGroup(parent);
270                 
271                 if (scope_depth < 0) {
272                  oh_search.addSubGroupsAsConditions(parent);
273                 }
274
275                 String JavaDoc sChildClass = (String JavaDoc) iter.next();
276
277                 AbstractChildObject emptyObj =
278                     (AbstractChildObject) Class
279                         .forName(sChildClass)
280                         .newInstance();
281
282
283                 // setting to search docs
284
oh_search.setSearchType(emptyObj);
285
286                 //add conditions if first time around
287
try {
288                     addSearchConditions(oh_search, condition);
289                 } catch(InvalidSearchObjectException e) {
290                     continue;
291                 }
292
293                 // reset select props
294
addSelectProperties(oh_search, selectProps);
295
296                 // reset order by props
297
addOrdering(oh_search, searchReq);
298
299                 // search docs
300

301                 List results = oh_search.executeSearch();
302                 allChildren.addAll(results);
303                 bFirstTime = false;
304             }
305
306             for (int i = 0; i < allChildren.size(); i++) {
307                 AbstractChildObject rdoc =
308                     (AbstractChildObject) allChildren.elementAt(i);
309
310                 if(HarmoniseNameResolver.hasValidDAVPath(rdoc)) {
311
312                     URL JavaDoc rsrc_url =
313                         new URL JavaDoc(
314                             HarmoniseNameResolver.getFullURL(rdoc, resource.getURL()));
315     
316                     ResourceImpl member = null;
317     
318                     if (rdoc instanceof AbstractParentObject) {
319                         member =
320                             new CollectionImpl(
321                                 rsrc_url,
322                                 HarmoniseNameResolver.getRealPath(rsrc_url),
323                                 null);
324                     } else {
325                         member =
326                             new ResourceImpl(
327                                 rsrc_url,
328                                 HarmoniseNameResolver.getRealPath(rsrc_url));
329                     }
330     
331                     member.setRequestContext(resource.getContext());
332                     resources.addElement(member);
333                 }
334             }
335         } catch (WebDAVException e) {
336             throw e;
337         } catch (Exception JavaDoc e) {
338             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
339             throw new WebDAVException(
340                 WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
341                 e.getMessage());
342         }
343
344         return resources;
345     }
346
347     private void addSelectProperties(Search oh_search, Vector selectProps) throws DataAccessException, HarmoniseFactoryException, DataStoreException {
348         AbstractProfiledObject profObj =
349             (AbstractProfiledObject) oh_search.getSearchType();
350         Profile prof = new Profile(this.m_dsi, profObj);
351
352         for (int i = 0; i < selectProps.size(); i++) {
353             PropertyName propName = (PropertyName) selectProps.elementAt(i);
354             String JavaDoc sPropertyName = propName.getLocal();
355
356         
357             if (propName.getNamespace().equals(NamespaceType.OHRM.getURI())) {
358                 if ((sPropertyName.equalsIgnoreCase("id") == false)
359                     && (sPropertyName.equals("status") == false)) {
360                     // creating propInst with doc profile so search has to be on docs first
361
AbstractPropertyInstance propInst =
362                         PropertyInstanceFactory.getPropertyInstance(
363                             m_dsi,
364                             PropertyFactory.getPropertyFromName(
365                                 m_dsi,
366                                 sPropertyName));
367
368                     oh_search.addSelectProperty(propInst);
369                 } else if (sPropertyName.equals("status") == true) {
370                     oh_search.addSelectColumn(
371                         profObj.getInstanceColumnRef(
372                             AbstractEditableObject.TAG_STATUS,
373                             false));
374                 }
375             } else if (
376                 propName.getNamespace().equals(NamespaceType.DAV.getURI())) {
377                 
378                 if (HarmoniseNameResolver.isMappedLiveProperty(sPropertyName)
379                     == true) {
380                     ColumnRef colref =
381                         profObj.getInstanceColumnRef(
382                             HarmoniseNameResolver.getTagForLiveProperty(
383                                 sPropertyName),
384                             false);
385
386                     
387                     oh_search.addSelectColumn(colref);
388                 }
389             }
390         }
391     }
392
393     private void addSearchConditions(Search oh_search, Object JavaDoc condition)
394         throws
395             HarmoniseFactoryException,
396             DataAccessException,
397             PopulateException,
398             NameResolverException,
399             WebDAVException,
400             DataStoreException, InvalidSearchObjectException {
401         if (condition instanceof SearchCondition) {
402             SearchCondition srchCond = (SearchCondition) condition;
403             String JavaDoc sOp = srchCond.getOperator();
404             oh_search.setStringingOperator(sOp);
405             for (int i = 0; i < srchCond.size(); i++) {
406                 try {
407                     addSearchConditions(oh_search, srchCond.getCondition(i));
408                 } catch (InvalidSearchObjectException e) {
409                     if(BasicSearchRequest.OPERATOR_AND.equalsIgnoreCase(sOp)) {
410                         throw e;
411                     }
412                 }
413             }
414         } else if (condition instanceof SearchPropertyConditionTerm) {
415             SearchPropertyConditionTerm term =
416                 (SearchPropertyConditionTerm) condition;
417
418             if (term.getPropertyName() != null
419                 && term.getPropertyName().getNamespace().equalsIgnoreCase(
420                     NamespaceType.OHRM.getURI())) {
421                 String JavaDoc sPropertyName = term.getPropertyLocalName();
422
423                 if ((sPropertyName.equalsIgnoreCase("id") == false)
424                     && (sPropertyName.equalsIgnoreCase("status") == false)
425                     && (sPropertyName.equalsIgnoreCase("title") == false)
426                     && (sPropertyName.equalsIgnoreCase("description") == false)) {
427                     Profile prof =
428                         new Profile(
429                             this.m_dsi,
430                             (AbstractProfiledObject) oh_search
431                                 .getSearchType());
432
433                     Property prop =
434                         PropertyFactory.getPropertyFromName(
435                             m_dsi,
436                             sPropertyName);
437                     if (prop != null) {
438                         AbstractPropertyInstance propInst =
439                             PropertyInstanceFactory.getPropertyInstance(
440                                 m_dsi,
441                                 prop);
442                         propInst.setProfile(prof);
443
444                         propInst.setOperator(term.getOperator());
445                         if (propInst instanceof GeneralPropertyInstance) {
446                             if(prop.getRange() instanceof DateRange) {
447                                 String JavaDoc sDateFormat = "yyyy-MM-dd";
448                                 String JavaDoc sDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
449                                 
450                                 String JavaDoc sTermVal = term.getValue();
451                                 
452                                 SimpleDateFormat formatter = new SimpleDateFormat();
453                                 
454                                 if(sTermVal.length() == sDateFormat.length()) {
455                                     formatter.applyPattern(sDateFormat);
456                                 } else if(sTermVal.length() == sDateTimeFormat.length()) {
457                                     formatter.applyPattern(sDateTimeFormat);
458                                 }
459                                                                 
460                                 try {
461                                     Date dt = formatter.parse(sTermVal);
462                                     ((GeneralPropertyInstance) propInst).addValue(dt);
463                                 } catch (ParseException e) {
464                                     throw new WebDAVException(WebDAVStatus.SC_BAD_REQUEST,"Date not formatted correctly in search condition term");
465                                 }
466                                 
467                             } else {
468                                 ((GeneralPropertyInstance) propInst).addValue(
469                                                                 term.getValue());
470                             }
471                             
472                         } else if (
473                             propInst instanceof ChildObjectPropertyInstance) {
474                             AbstractChildObject child =
475                                 HarmoniseNameResolver.getObjectFromURL(
476                                     m_dsi,
477                                     term.getValue());
478                             if(child != null) {
479                                 ((ChildObjectPropertyInstance) propInst).addValue(
480                                         child);
481                             }
482                             
483                         } else if (
484                             propInst instanceof ProfilePropertyInstance) {
485                             throw new WebDAVException(
486                                 WebDAVStatus.SC_BAD_REQUEST,
487                                 "Can't search on this property - "
488                                     + sPropertyName);
489                         }
490
491                     
492                         if(propInst.hasValues()) {
493                             oh_search.addConditionProperty(propInst);
494                         }
495                     } else {
496                         throw new WebDAVException(
497                             WebDAVStatus.SC_BAD_REQUEST,
498                             "Can't search on this property - " + sPropertyName);
499                     }
500                 } else if (sPropertyName.equalsIgnoreCase("title") == true) {
501                     ColumnRef nameCol =
502                         oh_search.getSearchType().getInstanceColumnRef(
503                             AbstractEditableObject.TAG_DISPLAY_NAME,
504                             false);
505                     Vector vec = new Vector();
506                     vec.add(term.getValue());
507                     oh_search.addConditionColumn(
508                         nameCol,
509                         term.getOperator(),
510                         vec);
511                     
512                 }
513             }
514         } else {
515             if (condition instanceof SearchConditionTerm
516                 && oh_search.getSearchType() instanceof TextResource) {
517
518                 try {
519                     SearchConditionTerm term = (SearchConditionTerm) condition;
520     
521                     ColumnRef contentCol =
522                         oh_search.getSearchType().getInstanceColumnRef(
523                             TextResource.TAG_CONTENT,
524                             false);
525                     Vector vec = new Vector();
526                     vec.add(term.getValue());
527                     oh_search.addConditionColumn(
528                         contentCol,
529                         term.getOperator(),
530                         vec);
531                     
532                 } catch (InvalidColumnReferenceException e) {
533                     //ignore and don't add the term if it's an invalid column
534
m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
535                 }
536             } else {
537                 throw new InvalidSearchObjectException();
538             }
539
540         }
541     }
542
543     private void addOrdering(Search oh_search, SearchRequest searchReq) throws DataStoreException, DataAccessException, HarmoniseFactoryException {
544         Vector orderBys = searchReq.getOrderByProperties();
545
546         if (orderBys != null) {
547             for (int i = 0; i < orderBys.size(); i++) {
548                 PropertyName pname = (PropertyName) orderBys.elementAt(i);
549                 String JavaDoc sOrderDirection = searchReq.getOrderByDirection(pname);
550                 String JavaDoc sPropertyName = pname.getLocal();
551
552                 if (pname
553                     .getNamespace()
554                     .equalsIgnoreCase(NamespaceType.OHRM.getURI())) {
555                     if (sPropertyName.equalsIgnoreCase("id") == true) {
556                         oh_search.setOrderBy(
557                             oh_search.getSearchType().getInstanceColumnRef(
558                                 AbstractEditableObject.ATTRIB_ID,
559                                 false),
560                             sOrderDirection);
561                     } else if (
562                         sPropertyName.equalsIgnoreCase("status") == true) {
563                         oh_search.setOrderBy(
564                             oh_search.getSearchType().getInstanceColumnRef(
565                                 AbstractEditableObject.TAG_STATUS,
566                                 false),
567                             sOrderDirection);
568                     } else {
569                         Profile prof =
570                             new Profile(
571                                 this.m_dsi,
572                                 (AbstractProfiledObject) oh_search
573                                     .getSearchType());
574                         AbstractPropertyInstance propInst =
575                             PropertyInstanceFactory.getPropertyInstance(
576                                 m_dsi,
577                                 PropertyFactory.getPropertyFromName(
578                                     m_dsi,
579                                     sPropertyName));
580                         propInst.setProfile(prof);
581
582                         oh_search.setOrderBy(propInst, sOrderDirection);
583                     }
584                 } else if (
585                     pname.getNamespace().equalsIgnoreCase(
586                         NamespaceType.DAV.getURI())) {
587                     if (HarmoniseNameResolver.isMappedLiveProperty(sPropertyName)
588                         == true) {
589                         ColumnRef colref =
590                             oh_search.getSearchType().getInstanceColumnRef(
591                                 HarmoniseNameResolver.getTagForLiveProperty(
592                                     sPropertyName),
593                                 false);
594                         oh_search.setOrderBy(colref, sOrderDirection);
595                     }
596                 }
597             }
598         }
599     }
600
601     private AbstractChildObject getWorkflowObject(ResourceImpl resource) throws WebDAVException {
602         AbstractChildObject child = null;
603
604         try {
605             URL JavaDoc url = resource.getURL();
606
607             if (HarmoniseNameResolver.isDAVRoot(url) == false
608                 && HarmoniseNameResolver.isArchivedVirtualCollection(url) == false) {
609                 child =
610                     HarmoniseNameResolver.getObjectFromURL(m_dsi, resource.getURL());
611             }
612         } catch (Exception JavaDoc e) {
613             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
614             throw new WebDAVException(
615                 WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
616                 "Problem occurred");
617         }
618
619         return child;
620     }
621
622     public boolean validate(SearchRequest searchReq) throws WebDAVException {
623         //TODO implement validation
624
return true;
625     }
626 }
Popular Tags