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 2009 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.
24 package org.collectionspace.services.common.context;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.Properties;
32 import javax.ws.rs.core.MultivaluedMap;
33 import javax.ws.rs.core.Request;
34 import javax.ws.rs.core.UriInfo;
36 import org.collectionspace.authentication.spi.AuthNContext;
37 import org.collectionspace.services.client.AuthorityClient;
38 import org.collectionspace.services.client.CollectionSpaceClient;
39 import org.collectionspace.services.client.IClientQueryParams;
40 import org.collectionspace.services.client.IQueryManager;
41 import org.collectionspace.services.client.workflow.WorkflowClient;
42 import org.collectionspace.services.common.ServiceMain;
43 import org.collectionspace.services.common.api.Tools;
44 import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
45 import org.collectionspace.services.common.config.PropertyItemUtils;
46 import org.collectionspace.services.common.config.ServiceConfigUtils;
47 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
48 import org.collectionspace.services.common.document.DocumentHandler;
49 import org.collectionspace.services.common.document.DocumentFilter;
50 import org.collectionspace.services.common.document.ValidatorHandler;
51 import org.collectionspace.services.common.security.SecurityContext;
52 import org.collectionspace.services.common.security.SecurityContextImpl;
53 import org.collectionspace.services.common.security.UnauthorizedException;
54 import org.collectionspace.services.config.ClientType;
55 import org.collectionspace.services.config.service.ObjectPartType;
56 import org.collectionspace.services.config.service.ServiceBindingType;
57 import org.collectionspace.services.config.tenant.RemoteClientConfig;
58 import org.collectionspace.services.config.tenant.RepositoryDomainType;
59 import org.collectionspace.services.config.tenant.TenantBindingType;
60 import org.collectionspace.services.config.types.PropertyItemType;
61 import org.collectionspace.services.config.types.PropertyType;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
66 * AbstractServiceContext
68 * $LastChangedRevision: $
83 @SuppressWarnings("rawtypes")
84 public abstract class AbstractServiceContextImpl<IT, OT>
85 implements ServiceContext<IT, OT> {
88 final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class);
90 /** The properties. */
91 Map<String, Object> properties = new HashMap<String, Object>();
92 /** The object part map. */
93 Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
94 /** The service binding. */
95 protected ServiceBindingType serviceBinding;
96 /** The tenant binding. */
97 private TenantBindingType tenantBinding;
98 /** repository domain used by the service */
99 private RepositoryDomainType repositoryDomain;
100 /** The override document type. */
101 private String overrideDocumentType = null;
102 /** The val handlers. */
103 private List<ValidatorHandler<IT, OT>> valHandlers = null;
104 /** The authority client -use for shared authority server */
105 private AuthorityClient authorityClient = null;
106 /** The doc handler. */
107 private DocumentHandler docHandler = null;
108 /** security context */
109 private SecurityContext securityContext;
110 /** The sessions JAX-RS URI information */
111 private UriInfo uriInfo;
112 /** The JAX-RS request information */
113 private Request requestInfo;
114 /** The current repository session */
115 private Object currentRepositorySession;
116 /** A reference count for the current repository session */
117 private int currentRepoSesssionRefCount = 0;
120 * Instantiates a new abstract service context impl.
122 private AbstractServiceContextImpl() {
123 // private constructor for singleton pattern
125 // request query params
126 /** The query params. */
127 private MultivaluedMap<String, String> queryParams;
130 * Instantiates a new abstract service context impl.
132 * @param serviceName the service name
134 * @throws UnauthorizedException the unauthorized exception
136 protected AbstractServiceContextImpl(String serviceName, UriInfo uriInfo) throws UnauthorizedException {
138 //establish security context
139 securityContext = new SecurityContextImpl(uriInfo);
140 //make sure tenant context exists
141 checkTenantContext();
143 String tenantId = securityContext.getCurrentTenantId();
144 if (AuthorizationCommon.ALL_TENANTS_MANAGER_TENANT_ID.equals(tenantId) ||
145 AuthNContext.ANONYMOUS_TENANT_ID.equals(tenantId)) {
146 // Tenant Manager has no tenant binding, so don't bother...
147 tenantBinding = null;
148 serviceBinding = null;
149 repositoryDomain = null;
151 //retrieve service bindings
152 TenantBindingConfigReaderImpl tReader =
153 ServiceMain.getInstance().getTenantBindingConfigReader();
154 tenantBinding = tReader.getTenantBinding(tenantId);
155 if (tenantBinding == null) {
156 String msg = "No tenant binding found for tenantId=" + tenantId
157 + " while processing request for service= " + serviceName;
159 throw new IllegalStateException(msg);
161 serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
162 if (serviceBinding == null) {
163 String msg = "No service binding found while processing request for "
164 + serviceName + " for tenant id=" + getTenantId()
165 + " name=" + getTenantName();
167 throw new IllegalStateException(msg);
169 if (logger.isDebugEnabled()) {
170 logger.debug("tenantId=" + tenantId
171 + " service binding=" + serviceBinding.getName());
173 repositoryDomain = tReader.getRepositoryDomain(tenantId, serviceName);
174 if (repositoryDomain != null) {
175 if (logger.isDebugEnabled()) {
176 logger.debug("tenantId=" + tenantId
177 + " repository doamin=" + repositoryDomain.getName());
183 public int getTimeoutParam(UriInfo ui) {
184 int result = DEFAULT_TX_TIMEOUT;
186 MultivaluedMap<String, String> queryParams = (ui == null) ? null : ui.getQueryParameters();
187 if (queryParams != null) {
188 String timeoutString = queryParams.getFirst(IClientQueryParams.IMPORT_TIMEOUT_PARAM);
189 if (timeoutString != null)
191 result = Integer.parseInt(timeoutString);
192 } catch (NumberFormatException e) {
193 logger.warn("Transaction timeout period parameter could not be parsed. The characters in the parameter string must all be decimal digits. The Import service will use the default timeout period instead.",
202 public int getTimeoutSecs() {
203 UriInfo uriInfo = this.getUriInfo();
204 return this.getTimeoutParam(uriInfo);
208 * Returns TRUE unless the "recordUpdates" query param is set with a value of either "false", "FALSE", or "0"
212 public boolean shouldUpdateCoreValues() {
213 boolean recordUpdates = true;
215 MultivaluedMap<String, String> queryParams = getQueryParams();
216 String paramValue = queryParams.getFirst(IClientQueryParams.UPDATE_CORE_VALUES);
217 if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.FALSE.toString())) { // Find our if the caller wants us to record updates
218 recordUpdates = false;
219 } else if (paramValue != null && paramValue.equals(Long.toString(0))) {
220 recordUpdates = false;
223 return recordUpdates;
227 * Default value is 'FALSE'
228 * If this returns true, it means that the refname values in referencing objects (records that reference authority or vocabulary terms) will be updated
229 * regardless of their current value. This is sometimes needed when refname values become stale for one of several reasons.
233 public boolean shouldForceUpdateRefnameReferences() {
234 boolean forceUpdates = false;
236 MultivaluedMap<String, String> queryParams = getQueryParams();
237 String paramValue = queryParams.getFirst(IClientQueryParams.FORCE_REFNAME_UPDATES);
238 if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.TRUE.toString())) { // Find our if the caller wants us to force refname updates
240 } else if (paramValue != null && paramValue.equals(Long.toString(1))) {
249 * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel()
252 public String getCommonPartLabel() {
253 return getCommonPartLabel(getServiceName());
257 * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel(java.lang.String)
259 public String getCommonPartLabel(String schemaName) {
260 return schemaName.toLowerCase() + PART_LABEL_SEPARATOR + PART_COMMON_LABEL;
264 * @see org.collectionspace.services.common.context.ServiceContext#getPartsMetadata()
267 public Map<String, ObjectPartType> getPartsMetadata() {
268 if (objectPartMap.size() != 0) {
269 return objectPartMap;
271 ServiceBindingUtils.getPartsMetadata(getServiceBinding(), objectPartMap);
272 return objectPartMap;
276 * Gets the properties for part.
278 * @param partLabel the part label
280 * @return the properties for part
282 public List<PropertyItemType> getPropertiesForPart(String partLabel) {
283 Map<String, ObjectPartType> partMap = getPartsMetadata();
284 ObjectPartType part = partMap.get(partLabel);
286 throw new RuntimeException("No such part found: " + partLabel);
288 List<PropertyType> propNodeList = part.getProperties();
289 return propNodeList.isEmpty() ? null : propNodeList.get(0).getItem();
293 * @param partLabel The name of the scehma part to search in
294 * @param propName The name of the property (or properties) to find
295 * @param qualified Whether the returned values should be qualified with the
296 * partLabel. This is when the property values are schema field references.
297 * @return List of property values for the matched property on the named schema part.
299 public List<String> getPropertyValuesForPart(String partLabel, String propName, boolean qualified) {
300 List<PropertyItemType> allProps = getPropertiesForPart(partLabel);
301 return PropertyItemUtils.getPropertyValuesByName(allProps, propName,
302 (qualified ? (partLabel + ":") : null));
306 * @param propName The name of the property (or properties) to find
307 * @param qualified Whether the returned values should be qualified with the
308 * partLabel. This is when the property values are schema field references.
309 * @return List of property values for the matched property on any schema part.
311 public List<String> getAllPartsPropertyValues(String propName, boolean qualified) {
312 return ServiceBindingUtils.getAllPartsPropertyValues(getServiceBinding(), propName, qualified);
316 * @see org.collectionspace.services.common.context.ServiceContext#getServiceBindingPropertyValue(java.lang.String)
318 public String getServiceBindingPropertyValue(String propName) {
319 return ServiceBindingUtils.getPropertyValue(getServiceBinding(), propName);
323 * Gets the common part properties.
325 * @return the common part properties
327 public List<PropertyItemType> getCommonPartProperties() {
328 return getPropertiesForPart(getCommonPartLabel());
332 * @param propName The name of the property (or properties) to find
333 * @param qualified Whether the returned values should be qualified with the
334 * partLabel. This is when the property values are schema field references.
335 * @return List of property values for the matched property on the common schema part.
337 public List<String> getCommonPartPropertyValues(String propName, boolean qualified) {
338 return getPropertyValuesForPart(getCommonPartLabel(), propName, qualified);
342 * @see org.collectionspace.services.common.context.ServiceContext#getQualifiedServiceName()
345 public String getQualifiedServiceName() {
346 return TenantBindingConfigReaderImpl.getTenantQualifiedServiceName(getTenantId(), getServiceName());
350 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryClientName()
353 public String getRepositoryClientName() {
354 if (repositoryDomain == null) {
357 return repositoryDomain.getRepositoryClient();
361 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryClientType()
364 public ClientType getRepositoryClientType() {
365 //assumption: there is only one repository client configured
366 return ServiceMain.getInstance().getClientType();
370 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryDomainName()
373 public String getRepositoryDomainName() {
374 if (repositoryDomain == null) {
377 return repositoryDomain.getName();
381 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryDomainName()
384 public String getRepositoryDomainStorageName() {
385 if (repositoryDomain == null) {
388 return repositoryDomain.getStorageName();
392 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryWorkspaceId()
395 public String getRepositoryWorkspaceId() {
396 return ServiceMain.getInstance().getWorkspaceId(getTenantId(), getServiceName());
400 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryWorkspaceName()
403 public String getRepositoryWorkspaceName() {
404 //service name is workspace name by convention
405 return serviceBinding.getName();
409 * @see org.collectionspace.services.common.context.ServiceContext#getServiceBinding()
412 public ServiceBindingType getServiceBinding() {
413 return serviceBinding;
417 * @see org.collectionspace.services.common.context.ServiceContext#getServiceName()
420 public String getServiceName() {
421 return serviceBinding.getName();
425 * @see org.collectionspace.services.common.context.ServiceContext#getDocumentType()
428 public String getDocumentType() {
429 // If they have not overridden the setting, use the type of the service
431 return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
435 public String getTenantQualifiedDoctype(String docType) {
436 // If they have not overridden the setting, use the type of the service
438 String result = ServiceBindingUtils.getTenantQualifiedDocType(this.getTenantId(), docType);
444 public String getTenantQualifiedDoctype() {
445 String docType = (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
446 return getTenantQualifiedDoctype(docType);
450 * @see org.collectionspace.services.common.context.ServiceContext#setDocumentType(java.lang.String)
453 public void setDocumentType(String docType) {
454 overrideDocumentType = docType;
458 * @see org.collectionspace.services.common.context.ServiceContext#getSecurityContext()
461 public SecurityContext getSecurityContext() {
462 return securityContext;
466 * @see org.collectionspace.services.common.context.ServiceContext#getUserId()
469 public String getUserId() {
470 return securityContext.getUserId();
474 * @see org.collectionspace.services.common.context.ServiceContext#getTenantId()
477 public String getTenantId() {
478 return securityContext.getCurrentTenantId();
482 * @see org.collectionspace.services.common.context.ServiceContext#getTenantName()
485 public String getTenantName() {
486 return securityContext.getCurrentTenantName();
490 * @see org.collectionspace.services.common.context.ServiceContext#getInput()
493 public abstract IT getInput();
496 * @see org.collectionspace.services.common.context.ServiceContext#setInput(java.lang.Object)
499 public abstract void setInput(IT input);
502 * @see org.collectionspace.services.common.context.ServiceContext#getOutput()
505 public abstract OT getOutput();
508 * @see org.collectionspace.services.common.context.ServiceContext#setOutput(java.lang.Object)
511 public abstract void setOutput(OT output);
514 * @see org.collectionspace.services.common.context.ServiceContext#getProperties()
517 public Map<String, Object> getProperties() {
522 * @see org.collectionspace.services.common.context.ServiceContext#setProperties(java.util.Map)
525 public void setProperties(Map<String, Object> props) {
526 properties.putAll(props);
530 * @see org.collectionspace.services.common.context.ServiceContext#getProperty(java.lang.String)
532 public Object getProperty(String name) {
533 return properties.get(name);
537 * @see org.collectionspace.services.common.context.ServiceContext#setProperty(java.lang.String, java.lang.Object)
539 public void setProperty(String name, Object o) {
540 properties.put(name, o);
544 * checkTenantContext makss sure tenant context exists
548 * @throws UnauthorizedException the unauthorized exception
550 private void checkTenantContext() throws UnauthorizedException {
552 String tenantId = securityContext.getCurrentTenantId();
553 if (tenantId == null) {
554 String msg = "Could not find tenant context";
556 throw new UnauthorizedException(msg);
561 * Helps to filter for queries that either want to include or exclude documents in deleted workflow states.
566 private static String buildWorkflowWhereClause(MultivaluedMap<String, String> queryParams) {
567 String result = null;
569 String includeDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED);
570 String includeOnlyDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED);
572 if (includeDeleted != null && includeDeleted.equalsIgnoreCase(Boolean.FALSE.toString())) {
573 result = String.format("(ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s')",
574 WorkflowClient.WORKFLOWSTATE_DELETED, WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED, WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
575 } else if (includeOnlyDeleted != null && includeOnlyDeleted.equalsIgnoreCase(Boolean.TRUE.toString())) {
576 result = String.format("(ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s')",
577 WorkflowClient.WORKFLOWSTATE_PROJECT, WorkflowClient.WORKFLOWSTATE_LOCKED, WorkflowClient.WORKFLOWSTATE_REPLICATED);
584 * Creates the document handler instance.
586 * @return the document handler
588 * @throws Exception the exception
590 private DocumentHandler createDocumentHandlerInstance() throws Exception {
591 docHandler = ServiceConfigUtils.createDocumentHandlerInstance(tenantBinding, serviceBinding);
593 // Create a default document filter
595 docHandler.setServiceContext(this);
596 DocumentFilter docFilter = docHandler.createDocumentFilter();
598 // If the context was created with query parameters,
599 // reflect the values of those parameters in the document filter
600 // to specify sort ordering, pagination, etc.
602 MultivaluedMap<String, String> queryParameters = this.getQueryParams();
603 if (queryParameters != null) {
604 docFilter.setSortOrder(queryParameters);
605 docFilter.setPagination(queryParameters);
606 String workflowWhereClause = buildWorkflowWhereClause(queryParameters);
607 if (workflowWhereClause != null) {
608 docFilter.appendWhereClause(workflowWhereClause, IQueryManager.SEARCH_QUALIFIER_AND);
612 docHandler.setDocumentFilter(docFilter);
618 * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHandler()
621 public DocumentHandler getDocumentHandler() throws Exception {
622 DocumentHandler result = docHandler;
623 // create a new instance if one does not yet exist
624 if (result == null) {
625 result = createDocumentHandlerInstance();
631 public void setDocumentHandler(DocumentHandler handler) throws Exception {
632 if (handler != null) {
633 docHandler = handler;
638 * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHanlder(javax.ws.rs.core.MultivaluedMap)
641 public DocumentHandler getDocumentHandler(MultivaluedMap<String, String> queryParams) throws Exception {
642 DocumentHandler result = getDocumentHandler();
643 DocumentFilter documentFilter = result.getDocumentFilter(); //to see results in debugger variables view
644 documentFilter.setPagination(queryParams);
649 * If this element is set in the service binding then use it otherwise
650 * assume that asserts are NOT disabled.
652 private boolean disableValidationAsserts() {
654 Boolean disableAsserts = getServiceBinding().isDisableAsserts();
655 result = (disableAsserts != null) ? disableAsserts : false;
660 * @see org.collectionspace.services.common.context.ServiceContext#getValidatorHandlers()
663 public List<ValidatorHandler<IT, OT>> getValidatorHandlers() throws Exception {
664 if (valHandlers != null) {
667 List<String> handlerClazzes = getServiceBinding().getValidatorHandler();
668 List<ValidatorHandler<IT, OT>> handlers = new ArrayList<ValidatorHandler<IT, OT>>(handlerClazzes.size());
669 ClassLoader tccl = Thread.currentThread().getContextClassLoader();
670 for (String clazz : handlerClazzes) {
671 clazz = clazz.trim();
673 Class<?> c = tccl.loadClass(clazz);
674 if (disableValidationAsserts() == false) {
675 // enable validation assertions
676 tccl.setClassAssertionStatus(clazz, true);
678 if (ValidatorHandler.class.isAssignableFrom(c)) {
679 handlers.add((ValidatorHandler) c.newInstance());
681 } catch (ClassNotFoundException e) {
682 String msg = String.format("Missing document validation handler: '%s'.", clazz);
684 logger.trace(msg, e);
687 valHandlers = handlers;
692 * If one doesn't already exist, use the default properties filename to load a set of properties that
693 * will be used to create an HTTP client to a CollectionSpace instance.
696 public AuthorityClient getClient() throws Exception {
697 AuthorityClient result = authorityClient;
699 if (authorityClient == null) {
700 result = authorityClient = getClient(CollectionSpaceClient.DEFAULT_CLIENT_PROPERTIES_FILENAME);
707 * Use the properties filename passed in to load the URL and credentials that will be used
708 * to create a new HTTP client.
710 * Never uses or resets the this.authorityClient member. Always creates a new HTTP client using
711 * the loaded properties.
714 * @see org.collectionspace.services.common.context.ServiceContext#getClient(java.lang.String)
717 public AuthorityClient getClient(String clientPropertiesFilename) throws Exception {
718 AuthorityClient result = null;
720 Properties inProperties = Tools.loadProperties(clientPropertiesFilename, true);
721 result = getClient(inProperties);
726 public AuthorityClient getClient(Properties inProperties) throws Exception {
727 AuthorityClient result = null;
729 String authorityClientClazz = getServiceBinding().getClientHandler();
730 ClassLoader tccl = Thread.currentThread().getContextClassLoader();
731 authorityClientClazz = authorityClientClazz.trim();
733 Class<?> c = tccl.loadClass(authorityClientClazz);
734 if (AuthorityClient.class.isAssignableFrom(c)) {
735 result = authorityClient = ((AuthorityClient) c.newInstance());
736 result.setClientProperties(inProperties);
738 logger.error(String.format("The service binding clientHandler class '%s' for '%s' service was not of type AuthorityClient.",
739 authorityClientClazz, this.getServiceName()));
741 } catch (ClassNotFoundException e) {
742 String msg = String.format("Missing document validation handler: '%s'.", authorityClientClazz);
744 logger.trace(msg, e);
751 public AuthorityClient getClient(RemoteClientConfig remoteClientConfig) throws Exception {
752 AuthorityClient result = null;
754 Properties properties = new Properties();
755 properties.setProperty(AuthorityClient.URL_PROPERTY, remoteClientConfig.getUrl());
756 properties.setProperty(AuthorityClient.USER_PROPERTY, remoteClientConfig.getUser());
757 properties.setProperty(AuthorityClient.PASSWORD_PROPERTY, remoteClientConfig.getPassword());
758 properties.setProperty(AuthorityClient.SSL_PROPERTY, remoteClientConfig.getSsl());
759 properties.setProperty(AuthorityClient.AUTH_PROPERTY, remoteClientConfig.getAuth());
762 String tenantId = remoteClientConfig.getTenantId();
763 if (tenantId != null) {
764 properties.setProperty(AuthorityClient.TENANT_ID_PROPERTY, tenantId);
766 String tenantName = remoteClientConfig.getTenantName();
767 if (tenantName != null) {
768 properties.setProperty(AuthorityClient.TENANT_NAME_PROPERTY, tenantName);
771 result = getClient(properties);
777 public void addValidatorHandler(ValidatorHandler<IT, OT> validator) throws Exception {
778 if (valHandlers == null) {
779 valHandlers = new ArrayList<ValidatorHandler<IT, OT>>();
781 valHandlers.add(validator);
785 * @see java.lang.Object#toString()
788 public String toString() {
789 StringBuilder msg = new StringBuilder();
790 msg.append("AbstractServiceContext [");
791 msg.append("service name=" + serviceBinding.getName() + " ");
792 msg.append("service version=" + serviceBinding.getVersion() + " ");
793 msg.append("tenant id=" + tenantBinding.getId() + " ");
794 msg.append("tenant name=" + tenantBinding.getName() + " ");
795 msg.append(tenantBinding.getDisplayName() + " ");
796 if (repositoryDomain != null) {
797 msg.append("tenant repository domain=" + repositoryDomain.getName());
799 for (Map.Entry<String, Object> entry : properties.entrySet()) {
800 msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
803 return msg.toString();
807 * @see org.collectionspace.services.common.context.ServiceContext#getQueryParams()
809 * When we first created these services, the RESTEasy query parameters used to be a modifiable map. That changed in a
810 * more recent version of RESTEasy, so we need to make a copy of the params into a modifiable map and return it instead.
813 public MultivaluedMap<String, String> getQueryParams() {
815 if (queryParams == null){
816 if (this.uriInfo != null){
817 queryParams = this.uriInfo.getQueryParameters();
820 if (queryParams == null){
821 queryParams = new org.jboss.resteasy.specimpl.MultivaluedMapImpl<String,String>();
823 return this.queryParams;
827 public MultivaluedMap<String, String> getQueryParamsPtr() {
828 return this.queryParams;
832 * @see org.collectionspace.services.common.context.ServiceContext#setQueryParams(javax.ws.rs.core.MultivaluedMap)
835 public void setQueryParams(MultivaluedMap<String, String> theQueryParams) {
836 this.queryParams = theQueryParams;
840 public void setUriInfo(UriInfo ui){
845 public UriInfo getUriInfo() {
850 public Request getRequestInfo() {
851 return this.requestInfo;
855 public void setRequestInfo(Request requestInfo) {
856 this.requestInfo = requestInfo;
860 * We expect the 'currentRepositorySession' member to be set only once per instance. Also, we expect only one open repository session
861 * per HTTP request. We'll log an error if we see more than one attempt to set a service context's current repo session.
863 * @see org.collectionspace.services.common.context.ServiceContext#setCurrentRepositorySession(java.lang.Object)
866 public void setCurrentRepositorySession(Object repoSession) throws Exception {
867 if (repoSession == null) {
868 String errMsg = "Setting a service context's repository session to null is not allowed.";
869 logger.error(errMsg);
870 throw new Exception(errMsg);
871 } else if (currentRepositorySession != null && currentRepositorySession != repoSession) {
872 String errMsg = "The current service context's repository session was replaced. This may cause unexpected behavior and/or data loss.";
873 logger.error(errMsg);
874 throw new Exception(errMsg);
877 currentRepositorySession = repoSession;
878 this.currentRepoSesssionRefCount++;
882 public void clearCurrentRepositorySession() {
883 if (this.currentRepoSesssionRefCount > 0) {
884 currentRepoSesssionRefCount--;
887 if (currentRepoSesssionRefCount == 0) {
888 this.currentRepositorySession = null;
893 public Object getCurrentRepositorySession() {
894 // TODO Auto-generated method stub
895 return currentRepositorySession;
899 public RepositoryDomainType getRepositoryDomain() {
900 return repositoryDomain;
904 public void setRepositoryDomain(RepositoryDomainType repositoryDomain) {
905 this.repositoryDomain = repositoryDomain;
909 * Check for a query parameter that indicates if we should force a sync even if the revision numbers indicate otherwise.
913 public boolean shouldForceSync() {
914 boolean forceSync = false;
916 MultivaluedMap<String, String> queryParams = getQueryParams();
917 String paramValue = queryParams.getFirst(IClientQueryParams.FORCE_SYCN);
918 if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.TRUE.toString())) { // Find our if the caller wants us to force refname updates
920 } else if (paramValue != null && paramValue.equals(Long.toString(1))) {