2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2011 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
25 package org.collectionspace.services.common.vocabulary;
27 import org.collectionspace.services.client.PoxPayloadIn;
28 import org.collectionspace.services.client.PoxPayloadOut;
29 import org.collectionspace.services.common.XmlTools;
30 import org.collectionspace.services.common.api.Tools;
31 import org.collectionspace.services.common.context.ServiceContext;
32 import org.collectionspace.services.common.relation.IRelationsManager;
33 import org.collectionspace.services.relation.RelationResource;
34 import org.collectionspace.services.relation.RelationsCommonList;
35 import org.collectionspace.services.relation.RelationsDocListItem;
36 import org.collectionspace.services.relation.RelationshipType;
38 import javax.ws.rs.core.MultivaluedMap;
39 import java.util.List;
42 * @author Laramie Crocker
44 public class Hierarchy {
46 public static final String directionQP = "direction";
47 public static final String direction_parents = "parents";
50 /**Call with the URI and CSID of the root element of the tree you wish to inspect. The uri can be a blank string.
51 * @param uri informational, optional - if not known, pass an empty String.
52 * @return String of XML document, including xml processing instruction, root node is "<hierarchy>".
54 public static String dive(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String itemcsid, String uri) {
55 String result = dive(ctx, itemcsid, uri, true);
56 result = "<?xml version='1.0' ?><hierarchy>"+result+"</hierarchy>";
58 result = XmlTools.prettyPrint(result);
59 } catch (Exception e){
65 private static String dive(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String itemcsid, String uri, boolean lookupFirstName) {
66 MultivaluedMap<String, String> queryParams = ctx.getUriInfo().getQueryParameters();
67 //Run getList() once as sent to get childListOuter:
68 queryParams.putSingle(IRelationsManager.PREDICATE_QP, RelationshipType.HAS_BROADER.value());
69 queryParams.putSingle(IRelationsManager.SUBJECT_QP, null);
70 queryParams.putSingle(IRelationsManager.SUBJECT_TYPE_QP, null);
71 queryParams.putSingle(IRelationsManager.OBJECT_QP, itemcsid);
72 queryParams.putSingle(IRelationsManager.OBJECT_TYPE_QP, null);
74 RelationResource relationResource = new RelationResource();
75 RelationsCommonList childListOuter = relationResource.getList(ctx); // Knows all query params because they are in the context.
76 List<RelationsCommonList.RelationListItem> childList = childListOuter.getRelationListItem();
78 StringBuffer sb = new StringBuffer();
80 if (lookupFirstName && childList.size() > 0) {
81 RelationsCommonList.RelationListItem firstItem = childList.get(0);
82 sb.append("<uri>" + firstItem.getObject().getUri() + "</uri>\r\n");
83 sb.append("<uri-called>" + uri + "</uri-called>\r\n");
84 sb.append("<name>" + firstItem.getObject().getName() + "</name><number>" + firstItem.getObject().getNumber() + "</number>\r\n");
86 sb.append("<uri>" + uri + "</uri>\r\n");
89 sb.append("<csid>" + itemcsid + "</csid>\r\n");
90 sb.append("<children>\r\n");
92 for (RelationsCommonList.RelationListItem item : childList) {
93 RelationsDocListItem parent = item.getObject();
94 RelationsDocListItem child = item.getSubject();
95 String childCSID = child.getCsid();
96 String childURI = child.getUri();
97 sb.append("<child>\r\n");
98 sb.append("<parent-uri>" +parent.getUri() + "</parent-uri>\r\n");
99 sb.append(" <name>" + child.getName() + "</name><number>" + child.getNumber() + "</number>\r\n");
100 String s = dive(ctx, childCSID, childURI, false);
102 sb.append("</child>\r\n");
104 sb.append("</children>\r\n");
105 return sb.toString();
108 public static String surface(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String itemcsid, String uri) {
109 String result = surface(ctx, itemcsid, uri, true).resultBuffer.toString();
110 result = "<?xml version='1.0' ?><hierarchy direction='"+direction_parents+"'>"+result+"</hierarchy>";
112 result = XmlTools.prettyPrint(result);
113 } catch (Exception e){
119 private static class SurfaceResultStruct {
120 public StringBuffer resultBuffer;
121 public boolean noParents = false;
124 private static SurfaceResultStruct surface(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String itemcsid, String uri, boolean first) {
125 MultivaluedMap<String, String> queryParams = ctx.getUriInfo().getQueryParameters();
126 //Run getList() once as sent to get parentListOuter:
127 queryParams.putSingle(IRelationsManager.PREDICATE_QP, RelationshipType.HAS_BROADER.value());
128 queryParams.putSingle(IRelationsManager.SUBJECT_QP, itemcsid);
129 queryParams.putSingle(IRelationsManager.SUBJECT_TYPE_QP, null);
130 queryParams.putSingle(IRelationsManager.OBJECT_QP, null);
131 queryParams.putSingle(IRelationsManager.OBJECT_TYPE_QP, null);
133 RelationResource relationResource = new RelationResource();
134 RelationsCommonList parentListOuter = relationResource.getList(ctx); // Knows all query params because they are in the context.
135 List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
137 StringBuffer sbOuter = new StringBuffer();
138 SurfaceResultStruct resultStruct = new SurfaceResultStruct();
139 resultStruct.resultBuffer = sbOuter;
142 sbOuter.append("<uri>" + uri + "</uri>\r\n");
143 sbOuter.append("<csid>" + itemcsid + "</csid>\r\n");
145 StringBuffer sb = new StringBuffer();
148 String otherNames="";
150 String otherNumbers = "";
152 sb.append("<parents>\r\n");
153 if (parentList.size()==0){
154 resultStruct.noParents = true;
157 for (RelationsCommonList.RelationListItem item : parentList) {
158 resultStruct.noParents = false;
159 RelationsDocListItem parent = item.getObject();
160 RelationsDocListItem child = item.getSubject();
161 String parentCSID =parent.getCsid();
162 String parentURI = parent.getUri();
164 String aName = child.getName();
165 String aNumber = child.getNumber();
166 if (name.length()>0 && (!name.equals(aName))){
167 otherNames = otherNames+";"+aName;
171 if (number.length()>0 && (!number.equals(aNumber))){
172 otherNumbers = otherNumbers+";"+aNumber;
177 sb.append("<parent>\r\n");
178 //sb.append("<parent-uri>" +parentURI + "</parent-uri>\r\n");
180 SurfaceResultStruct struct = surface(ctx, parentCSID, parentURI, false);
181 StringBuffer surfaceResult = struct.resultBuffer;
183 if (struct.noParents){
184 //when there are no more parents, there is no way to look up the name and number, so use this trick:
185 sb.append("<name>" + parent.getName() + "</name><number>" + parent.getNumber() + "</number>\r\n");
188 sb.append(surfaceResult);
189 sb.append("</parent>\r\n");
191 sb.append("</parents>\r\n");
194 if (Tools.notBlank(name))sbOuter.append(" <name>" +name + "</name>\r\n");
195 if (Tools.notBlank(otherNames)) sbOuter.append(" <name-mismatches-by-parents>" +otherNames + "</name-mismatches-by-parents>\r\n");
197 if (Tools.notBlank(number)) sbOuter.append("<number>" +number + "</number>\r\n");
198 if (Tools.notBlank(otherNumbers)) sbOuter.append(" <number-mismatches-by-parents>" +otherNumbers + "</number-mismatches-by-parents>\r\n");