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 initializeAuthorities(app.getResourceMap());
50 logger.log(Level.INFO, String.format("%tc [INFO] CollectionSpace Services' JAX-RS application started.", new Date()));
51 } catch (Exception e) {
53 throw new RuntimeException(e);
58 public void contextDestroyed(ServletContextEvent event) {
59 logger.log(Level.INFO, "[INFO] Shutting down the CollectionSpace Services' JAX-RS application.");
60 //Do something if needed.
61 logger.log(Level.INFO, "[INFO] CollectionSpace Services' JAX-RS application stopped.");
65 * Initialize all authorities and vocabularies defined in the service bindings.
69 public void initializeAuthorities(ResourceMap resourceMap) throws Exception {
70 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
71 Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
72 for (TenantBindingType tenantBindings : tenantBindingsTable.values()) {
73 CSpaceTenant tenant = new CSpaceTenant(tenantBindings.getId(), tenantBindings.getName());
74 for (ServiceBindingType serviceBinding : tenantBindings.getServiceBindings()) {
75 AuthorityInstanceList element = serviceBinding.getAuthorityInstanceList();
76 if (element != null && element.getAuthorityInstance() != null) {
77 List<AuthorityInstanceType> authorityInstanceList = element.getAuthorityInstance();
78 for (AuthorityInstanceType authorityInstance : authorityInstanceList) {
80 initializeAuthorityInstance(resourceMap, authorityInstance, serviceBinding, tenant);
81 } catch (Exception e) {
82 logger.log(Level.SEVERE, "Could not initialize authorities and authority terms: " + e.getMessage());
91 @SuppressWarnings("rawtypes")
92 private AuthorityClient getAuthorityClient(String classname) throws Exception {
93 Class clazz = Class.forName(classname.trim());
94 Constructor co = clazz.getConstructor(null);
95 Object classInstance = co.newInstance(null);
96 return (AuthorityClient) classInstance;
100 * Check to see if an an authority instance and its corresponding terms exist. If not, try to create them.
102 private void initializeAuthorityInstance(ResourceMap resourceMap, AuthorityInstanceType authorityInstance, ServiceBindingType serviceBinding, CSpaceTenant tenant) throws Exception {
104 Response response = null;
105 String serviceName = serviceBinding.getName();
107 AuthZ.get().login(tenant);
108 String clientClassName = serviceBinding.getClientHandler();
109 AuthorityClient client = getAuthorityClient(clientClassName);
110 String authoritySpecifier = RefName.shortIdToPath(authorityInstance.getTitleRef()); // e.g., urn:cspace:name(ulan)
113 // Test to see if the authority instance exists already.
115 AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(serviceName.toLowerCase());
117 response = authorityResource.get(null, null, authoritySpecifier);
118 } catch (CSWebApplicationException e) {
119 response = e.getResponse(); // If the authority doesn't exist, we expect a 404 error
123 // If it doesn't exist (status is not 200), then try to create the authority instance
125 status = response.getStatus();
126 if (status != Response.Status.OK.getStatusCode()) {
127 String xmlPayload = client.createAuthorityInstance(authorityInstance.getTitleRef(), authorityInstance.getTitle());
128 response = authorityResource.createAuthority(xmlPayload);
129 status = response.getStatus();
130 if (status != Response.Status.CREATED.getStatusCode()) {
131 throw new CSWebApplicationException(response);
135 if (status == Response.Status.OK.getStatusCode()) {
136 logger.log(Level.FINE, String.format("Authority of type '%s' with the short ID of '%s' existed already.",
137 serviceName, authorityInstance.getTitleRef()));
138 } else if (status == Response.Status.CREATED.getStatusCode()) {
139 logger.log(Level.INFO, String.format("Created a new authority of type '%s' with the short ID of '%s'.",
140 serviceName, authorityInstance.getTitleRef()));
142 logger.log(Level.WARNING, String.format("Unknown status '%d' encountered when creating or fetching authority of type '%s' with the short ID of '%s'.",
143 serviceName, authorityInstance.getTitleRef()));
147 // Finally, try to create or verify the authority terms.
149 initializeAuthorityInstanceTerms(authorityResource, client, authoritySpecifier, resourceMap, authorityInstance, serviceName, tenant);
152 private void initializeAuthorityInstanceTerms(
153 AuthorityResource authorityResource,
154 AuthorityClient client,
155 String authoritySpecifier,
156 ResourceMap resourceMap,
157 AuthorityInstanceType authorityInstance,
159 CSpaceTenant tenant) throws Exception {
162 Response response = null;
164 TermList termListElement = authorityInstance.getTermList();
165 for (Term term : termListElement.getTerm()) {
167 // Check to see if the term already exists
170 String termSpecifier = RefName.shortIdToPath(term.getId());
171 authorityResource.getAuthorityItem(null, null, resourceMap, authoritySpecifier, termSpecifier);
172 status = Response.Status.OK.getStatusCode();
173 } catch (CSWebApplicationException e) {
174 response = e.getResponse(); // If the authority doesn't exist, we expect a 404 error
175 status = response.getStatus();
179 // If the term doesn't exist, create it.
181 if (status != Response.Status.OK.getStatusCode()) {
182 String termShortId = term.getId();
183 String termDisplayName = term.getContent().trim();
184 String xmlPayload = client.createAuthorityItemInstance(termShortId, termDisplayName);
186 authorityResource.createAuthorityItem(resourceMap, null, authoritySpecifier, xmlPayload);
187 logger.log(Level.INFO, String.format("Created a new term '%s:%s' in the authority of type '%s' with the short ID of '%s'.",
188 termDisplayName, termShortId, serviceName, authorityInstance.getTitleRef()));
189 } catch (CSWebApplicationException e) {
190 response = e.getResponse();
191 status = response.getStatus();
192 if (status != Response.Status.CREATED.getStatusCode()) {
193 throw new CSWebApplicationException(response);