1 package org.collectionspace.services.jaxrs;
3 import javax.servlet.ServletContextEvent;
4 import javax.ws.rs.core.Response;
6 import org.jboss.resteasy.core.Dispatcher;
7 import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
9 import org.collectionspace.authentication.CSpaceTenant;
10 import org.collectionspace.services.authorization.AuthZ;
11 import org.collectionspace.services.client.AuthorityClient;
12 import org.collectionspace.services.common.CSWebApplicationException;
13 import org.collectionspace.services.common.ResourceMap;
14 import org.collectionspace.services.common.ServiceMain;
15 import org.collectionspace.services.common.api.RefName;
16 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
17 import org.collectionspace.services.common.vocabulary.AuthorityResource;
18 import org.collectionspace.services.config.service.AuthorityInstanceType;
19 import org.collectionspace.services.config.service.ServiceBindingType;
20 import org.collectionspace.services.config.service.ServiceBindingType.AuthorityInstanceList;
21 import org.collectionspace.services.config.service.Term;
22 import org.collectionspace.services.config.service.TermList;
23 import org.collectionspace.services.config.tenant.TenantBindingType;
25 import java.lang.reflect.Constructor;
26 import java.util.Date;
27 import java.util.Hashtable;
28 import java.util.List;
29 import java.util.logging.Level;
31 public class CSpaceResteasyBootstrap extends ResteasyBootstrap {
33 java.util.logging.Logger logger = java.util.logging.Logger.getAnonymousLogger();
36 public void contextInitialized(ServletContextEvent event) {
39 // This call to super instantiates and initializes our JAX-RS application class.
40 // The application class is org.collectionspace.services.jaxrs.CollectionSpaceJaxRsApplication.
42 logger.log(Level.INFO, String.format("%tc [INFO] Starting up the CollectionSpace Services' JAX-RS application.", new Date()));
43 super.contextInitialized(event);
44 CollectionSpaceJaxRsApplication app = (CollectionSpaceJaxRsApplication)deployment.getApplication();
45 Dispatcher disp = deployment.getDispatcher();
46 disp.getDefaultContextObjects().put(ResourceMap.class, app.getResourceMap());
48 String initAuthsString = System.getProperty("org.collectionspace.services.authorities.init", Boolean.TRUE.toString()); // Property can be set in the tomcat/bin/setenv.sh (or setenv.bat) file
49 if (Boolean.valueOf(initAuthsString) == true) {
50 initializeAuthorities(app.getResourceMap());
53 logger.log(Level.INFO, String.format("%tc [INFO] CollectionSpace Services' JAX-RS application started.", new Date()));
54 } catch (Exception e) {
56 throw new RuntimeException(e);
61 public void contextDestroyed(ServletContextEvent event) {
62 logger.log(Level.INFO, "[INFO] Shutting down the CollectionSpace Services' JAX-RS application.");
63 //Do something if needed.
64 logger.log(Level.INFO, "[INFO] CollectionSpace Services' JAX-RS application stopped.");
68 * Initialize all authorities and vocabularies defined in the service bindings.
72 public void initializeAuthorities(ResourceMap resourceMap) throws Exception {
73 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
74 Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
75 for (TenantBindingType tenantBindings : tenantBindingsTable.values()) {
76 CSpaceTenant tenant = new CSpaceTenant(tenantBindings.getId(), tenantBindings.getName());
77 for (ServiceBindingType serviceBinding : tenantBindings.getServiceBindings()) {
78 AuthorityInstanceList element = serviceBinding.getAuthorityInstanceList();
79 if (element != null && element.getAuthorityInstance() != null) {
80 List<AuthorityInstanceType> authorityInstanceList = element.getAuthorityInstance();
81 for (AuthorityInstanceType authorityInstance : authorityInstanceList) {
83 initializeAuthorityInstance(resourceMap, authorityInstance, serviceBinding, tenant);
84 } catch (Exception e) {
85 logger.log(Level.SEVERE, "Could not initialize authorities and authority terms: " + e.getMessage());
94 @SuppressWarnings("rawtypes")
95 private AuthorityClient getAuthorityClient(String classname) throws Exception {
96 Class clazz = Class.forName(classname.trim());
97 Constructor co = clazz.getConstructor(null);
98 Object classInstance = co.newInstance(null);
99 return (AuthorityClient) classInstance;
103 * Check to see if an an authority instance and its corresponding terms exist. If not, try to create them.
105 private void initializeAuthorityInstance(ResourceMap resourceMap, AuthorityInstanceType authorityInstance, ServiceBindingType serviceBinding, CSpaceTenant tenant) throws Exception {
107 Response response = null;
108 String serviceName = serviceBinding.getName();
110 AuthZ.get().login(tenant);
111 String clientClassName = serviceBinding.getClientHandler();
112 AuthorityClient client = getAuthorityClient(clientClassName);
113 String authoritySpecifier = RefName.shortIdToPath(authorityInstance.getTitleRef()); // e.g., urn:cspace:name(ulan)
116 // Test to see if the authority instance exists already.
118 AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(serviceName.toLowerCase());
120 response = authorityResource.get(null, null, authoritySpecifier);
121 } catch (CSWebApplicationException e) {
122 response = e.getResponse(); // If the authority doesn't exist, we expect a 404 error
126 // If it doesn't exist (status is not 200), then try to create the authority instance
128 status = response.getStatus();
129 if (status != Response.Status.OK.getStatusCode()) {
130 String xmlPayload = client.createAuthorityInstance(authorityInstance.getTitleRef(), authorityInstance.getTitle());
131 response = authorityResource.createAuthority(xmlPayload);
132 status = response.getStatus();
133 if (status != Response.Status.CREATED.getStatusCode()) {
134 throw new CSWebApplicationException(response);
138 if (status == Response.Status.OK.getStatusCode()) {
139 logger.log(Level.FINE, String.format("Authority of type '%s' with the short ID of '%s' existed already.",
140 serviceName, authorityInstance.getTitleRef()));
141 } else if (status == Response.Status.CREATED.getStatusCode()) {
142 logger.log(Level.INFO, String.format("Created a new authority of type '%s' with the short ID of '%s'.",
143 serviceName, authorityInstance.getTitleRef()));
145 logger.log(Level.WARNING, String.format("Unknown status '%d' encountered when creating or fetching authority of type '%s' with the short ID of '%s'.",
146 serviceName, authorityInstance.getTitleRef()));
150 // Finally, try to create or verify the authority terms.
152 initializeAuthorityInstanceTerms(authorityResource, client, authoritySpecifier, resourceMap, authorityInstance, serviceName, tenant);
155 private void initializeAuthorityInstanceTerms(
156 AuthorityResource authorityResource,
157 AuthorityClient client,
158 String authoritySpecifier,
159 ResourceMap resourceMap,
160 AuthorityInstanceType authorityInstance,
162 CSpaceTenant tenant) throws Exception {
165 Response response = null;
167 TermList termListElement = authorityInstance.getTermList();
168 if (termListElement == null) {
172 for (Term term : termListElement.getTerm()) {
174 // Check to see if the term already exists
177 String termSpecifier = RefName.shortIdToPath(term.getId());
178 authorityResource.getAuthorityItem(null, null, resourceMap, authoritySpecifier, termSpecifier);
179 status = Response.Status.OK.getStatusCode();
180 } catch (CSWebApplicationException e) {
181 response = e.getResponse(); // If the authority doesn't exist, we expect a 404 error
182 status = response.getStatus();
186 // If the term doesn't exist, create it.
188 if (status != Response.Status.OK.getStatusCode()) {
189 String termShortId = term.getId();
190 String termDisplayName = term.getContent().trim();
191 String xmlPayload = client.createAuthorityItemInstance(termShortId, termDisplayName);
193 authorityResource.createAuthorityItem(resourceMap, null, authoritySpecifier, xmlPayload);
194 logger.log(Level.INFO, String.format("Created a new term '%s:%s' in the authority of type '%s' with the short ID of '%s'.",
195 termDisplayName, termShortId, serviceName, authorityInstance.getTitleRef()));
196 } catch (CSWebApplicationException e) {
197 response = e.getResponse();
198 status = response.getStatus();
199 if (status != Response.Status.CREATED.getStatusCode()) {
200 throw new CSWebApplicationException(response);