]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
4f5642122ccc7dfd395d38ef1adfa50604f22e19
[tmp/jakarta-migration.git] /
1 /**\r
2  *  This document is a part of the source code and related artifacts\r
3  *  for CollectionSpace, an open source collections management system\r
4  *  for museums and related institutions:\r
5 \r
6  *  http://www.collectionspace.org\r
7  *  http://wiki.collectionspace.org\r
8 \r
9  *  Copyright 2009 University of California at Berkeley\r
10 \r
11  *  Licensed under the Educational Community License (ECL), Version 2.0.\r
12  *  You may not use this file except in compliance with this License.\r
13 \r
14  *  You may obtain a copy of the ECL 2.0 License at\r
15 \r
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
17 \r
18  *  Unless required by applicable law or agreed to in writing, software\r
19  *  distributed under the License is distributed on an "AS IS" BASIS,\r
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
21  *  See the License for the specific language governing permissions and\r
22  *  limitations under the License.\r
23  */\r
24 package org.collectionspace.services.common.vocabulary;\r
25 \r
26 import java.util.ArrayList;\r
27 import java.util.Collection;\r
28 import java.util.HashMap;\r
29 import java.util.Iterator;\r
30 import java.util.List;\r
31 import java.util.Map;\r
32 \r
33 import org.nuxeo.ecm.core.api.ClientException;\r
34 import org.nuxeo.ecm.core.api.DocumentModel;\r
35 import org.nuxeo.ecm.core.api.DocumentModelList;\r
36 import org.slf4j.Logger;\r
37 import org.slf4j.LoggerFactory;\r
38 \r
39 import org.collectionspace.services.common.ServiceMain;\r
40 import org.collectionspace.services.common.context.ServiceContext;\r
41 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;\r
42 import org.collectionspace.services.common.authorityref.AuthorityRefList;\r
43 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
44 import org.collectionspace.services.common.context.ServiceBindingUtils;\r
45 import org.collectionspace.services.common.document.DocumentException;\r
46 import org.collectionspace.services.common.document.DocumentNotFoundException;\r
47 import org.collectionspace.services.common.document.DocumentUtils;\r
48 import org.collectionspace.services.common.document.DocumentWrapper;\r
49 import org.collectionspace.services.common.repository.RepositoryClient;\r
50 import org.collectionspace.services.common.service.ServiceBindingType;\r
51 import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
52 \r
53 /**\r
54  * RefNameServiceUtils is a collection of services utilities related to refName usage.\r
55  *\r
56  * $LastChangedRevision: $\r
57  * $LastChangedDate: $\r
58  */\r
59 public class RefNameServiceUtils {\r
60 \r
61     private final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
62 \r
63     public static AuthorityRefDocList getAuthorityRefDocs(ServiceContext ctx,\r
64             RepositoryClient repoClient,\r
65             String serviceType,\r
66             String refName,\r
67             int pageSize, int pageNum, boolean computeTotal) throws DocumentException, DocumentNotFoundException {\r
68         AuthorityRefDocList wrapperList = new AuthorityRefDocList();\r
69         List<AuthorityRefDocList.AuthorityRefDocItem> list =\r
70                 wrapperList.getAuthorityRefDocItem();\r
71         TenantBindingConfigReaderImpl tReader =\r
72                 ServiceMain.getInstance().getTenantBindingConfigReader();\r
73         List<ServiceBindingType> servicebindings = tReader.getServiceBindingsByType(ctx.getTenantId(), serviceType);\r
74         if (servicebindings == null || servicebindings.isEmpty()) {\r
75             return null;\r
76         }\r
77         // Need to escape the quotes in the refName\r
78         // TODO What if they are already escaped?\r
79         String escapedRefName = refName.replaceAll("'", "\\\\'");\r
80 //      String domain = \r
81 //              tReader.getTenantBinding(ctx.getTenantId()).getRepositoryDomain();\r
82         ArrayList<String> docTypes = new ArrayList<String>();\r
83         Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
84         Map<String, Map<String, String>> authRefFieldsByService = new HashMap<String, Map<String, String>>();\r
85         StringBuilder whereClause = new StringBuilder();\r
86         boolean fFirst = true;\r
87         List<String> authRefFieldPaths = new ArrayList<String>();\r
88         for (ServiceBindingType sb : servicebindings) {\r
89             authRefFieldPaths =\r
90                     ServiceBindingUtils.getAllPartsPropertyValues(sb,\r
91                     ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES);\r
92             if (authRefFieldPaths.isEmpty()) {\r
93                 continue;\r
94             }\r
95             String authRefPath = "";\r
96             String ancestorAuthRefFieldName = "";\r
97             Map<String, String> authRefFields = new HashMap<String, String>();\r
98             for (int i = 0; i < authRefFieldPaths.size(); i++) {\r
99                 // fieldName = DocumentUtils.getDescendantOrAncestor(authRefFields.get(i));\r
100                 authRefPath = authRefFieldPaths.get(i);\r
101                 ancestorAuthRefFieldName = DocumentUtils.getAncestorAuthRefFieldName(authRefFieldPaths.get(i));\r
102                 authRefFields.put(authRefPath, ancestorAuthRefFieldName);\r
103             }\r
104 \r
105             String docType = sb.getObject().getName();\r
106             queriedServiceBindings.put(docType, sb);\r
107             authRefFieldsByService.put(docType, authRefFields);\r
108             docTypes.add(docType);\r
109             /*\r
110             // HACK - need to get qualified properties from the ServiceBinding\r
111             String prefix = "";\r
112             if(docType.equalsIgnoreCase("Intake"))\r
113             prefix = "intakes_common:";\r
114             else if(docType.equalsIgnoreCase("Loanin"))\r
115             prefix = "loansin_common:";\r
116             else if(docType.equalsIgnoreCase("Acquisition"))\r
117             prefix = "acquisitions_common:";\r
118              */\r
119             Collection<String> fields = authRefFields.values();\r
120             for (String field : fields) {\r
121                 // Build up the where clause for each authRef field\r
122                 if (fFirst) {\r
123                     fFirst = false;\r
124                 } else {\r
125                     whereClause.append(" OR ");\r
126                 }\r
127                 //whereClause.append(prefix);\r
128                 whereClause.append(field);\r
129                 whereClause.append("='");\r
130                 whereClause.append(escapedRefName);\r
131                 whereClause.append("'");\r
132             }\r
133         }\r
134         String whereClauseStr = whereClause.toString(); // for debugging\r
135         if (fFirst) // found no authRef fields - nothing to query\r
136         {\r
137             return wrapperList;\r
138         }\r
139         String fullQuery = whereClause.toString(); // for debug\r
140         // Now we have to issue the search\r
141         DocumentWrapper<DocumentModelList> docListWrapper = repoClient.findDocs(ctx,\r
142                 docTypes, whereClause.toString(), pageSize, pageNum, computeTotal);\r
143         // Now we gather the info for each document into the list and return\r
144         DocumentModelList docList = docListWrapper.getWrappedObject();\r
145         Iterator<DocumentModel> iter = docList.iterator();\r
146         while (iter.hasNext()) {\r
147             DocumentModel docModel = iter.next();\r
148             AuthorityRefDocList.AuthorityRefDocItem ilistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
149             String csid = NuxeoUtils.extractId(docModel.getPathAsString());\r
150             String docType = docModel.getDocumentType().getName();\r
151             ServiceBindingType sb = queriedServiceBindings.get(docType);\r
152             if (sb == null) {\r
153                 throw new RuntimeException(\r
154                         "getAuthorityRefDocs: No Service Binding for docType: " + docType);\r
155             }\r
156             String serviceContextPath = "/" + sb.getName().toLowerCase() + "/";\r
157             // The id and URI are the same on all doctypes\r
158             ilistItem.setDocId(csid);\r
159             ilistItem.setUri(serviceContextPath + csid);\r
160             ilistItem.setDocType(docType);\r
161             ilistItem.setDocNumber(\r
162                     ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel));\r
163             ilistItem.setDocName(\r
164                     ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel));\r
165             // Now, we have to loop over the authRefFieldsByService to figure\r
166             // out which field matched this. Ignore multiple matches.\r
167             Map<String,String> matchingAuthRefFields = authRefFieldsByService.get(docType);\r
168             if (matchingAuthRefFields == null || matchingAuthRefFields.isEmpty()) {\r
169                 throw new RuntimeException(\r
170                         "getAuthorityRefDocs: internal logic error: can't fetch authRefFields for DocType.");\r
171             }\r
172             String authRefAncestorField = "";\r
173             String authRefDescendantField = "";\r
174             String sourceField = "";\r
175             boolean fRefFound = false;\r
176             // Use this if we go to qualified field names\r
177             for (String path : matchingAuthRefFields.keySet()) {\r
178                 try {\r
179                     authRefAncestorField = (String) matchingAuthRefFields.get(path);\r
180                     authRefDescendantField = DocumentUtils.getDescendantOrAncestor(path);\r
181                     String[] strings = authRefAncestorField.split(":");\r
182                     if (strings.length != 2) {\r
183                         throw new RuntimeException(\r
184                                 "getAuthorityRefDocs: Bad configuration of path to authority reference field.");\r
185                     }\r
186                     // strings[0] holds a schema name, such as "intakes_common"\r
187                     //\r
188                     // strings[1] holds:\r
189                     // * The name of an authority reference field, such as "depositor";\r
190                     //   or\r
191                     // * The name of an ancestor (e.g. parent, grandparent ...) field,\r
192                     //   such as "fieldCollectors", of a repeatable authority reference\r
193                     //   field, such as "fieldCollector".\r
194                     Object fieldValue = docModel.getProperty(strings[0], strings[1]);\r
195                     fRefFound = refNameFoundInField(refName, fieldValue);\r
196                     if (fRefFound) {\r
197                         sourceField = authRefDescendantField;\r
198                         ilistItem.setSourceField(sourceField);\r
199                         // FIXME Returns only the first field in which the refName is found.\r
200                         // We may want to return all; this may require multiple sourceFields\r
201                         // in the list item schema; or else multiple list items, one per sourceField.\r
202                         // See CSPACE-2863 for a discussion of how this might be handled.\r
203                         break;\r
204                     }\r
205 \r
206                 } catch (ClientException ce) {\r
207                     throw new RuntimeException(\r
208                             "getAuthorityRefDocs: Problem fetching: " + sourceField, ce);\r
209                 }\r
210             }\r
211             // Used before going to schema-qualified field names.\r
212             /*\r
213             for(String field:matchingAuthRefFields){\r
214             try {\r
215             if(refName.equals(docModel.getPropertyValue(field))) {\r
216             ilistItem.setSourceField(field);\r
217             fRefFound = true;\r
218             break;\r
219             }\r
220             } catch(ClientException ce) {\r
221             throw new RuntimeException(\r
222             "getAuthorityRefDocs: Problem fetching: "+field, ce);\r
223             }\r
224             }\r
225              * \r
226              */\r
227             if (!fRefFound) {\r
228                 throw new RuntimeException(\r
229                         "getAuthorityRefDocs: Could not find refname in object:"\r
230                         + docType + ":" + csid);\r
231             }\r
232             list.add(ilistItem);\r
233         }\r
234         return wrapperList;\r
235     }\r
236 \r
237     /*\r
238      * Identifies whether the refName was found in the supplied field.\r
239      *\r
240      * Only works for:\r
241      * * Scalar fields\r
242      * * Repeatable scalar fields (aka multi-valued fields)\r
243      *\r
244      * Does not work for:\r
245      * * Structured fields (complexTypes)\r
246      * * Repeatable structured fields (repeatable complexTypes)\r
247      */\r
248     private static boolean refNameFoundInField(String refName, Object fieldValue) {\r
249 \r
250         boolean result = false;\r
251         if (fieldValue instanceof List) {\r
252             List<String> fieldValueList = (List) fieldValue;\r
253             for (String listItemValue : fieldValueList) {\r
254                 if (refName.equals(listItemValue)) {\r
255                     result = true;\r
256                     break;\r
257                 }\r
258 \r
259             }\r
260         } else {\r
261             if (refName.equals(fieldValue)) {\r
262                 result = true;\r
263             }\r
264         }\r
265         return result;\r
266     }\r
267 }\r
268 \r