Coverage Report - org.kuali.rice.ksb.api.bus.support.RestServiceDefinition
 
Classes in this File Line Coverage Branch Coverage Complexity
RestServiceDefinition
70%
43/61
59%
19/32
2.235
 
 1  
 /*
 2  
  * Copyright 2006-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.kuali.rice.ksb.api.bus.support;
 18  
 
 19  
 import java.util.List;
 20  
 import java.util.Map;
 21  
 
 22  
 import javax.ws.rs.Path;
 23  
 
 24  
 import org.apache.commons.collections.BidiMap;
 25  
 import org.apache.commons.collections.bidimap.DualHashBidiMap;
 26  
 import org.kuali.rice.core.api.config.ConfigurationException;
 27  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 28  
 import org.kuali.rice.ksb.api.KsbApiConstants;
 29  
 import org.kuali.rice.ksb.api.bus.ServiceConfiguration;
 30  
 
 31  
 /**
 32  
  * Service definition for RESTful services.  A JAX-WS service has a resource
 33  
  * class, which is the class or interface marked by the JAX-WS annotations
 34  
  * (e.g. @Path, @GET, etc).  This may or may not be the implementation class.
 35  
  * 
 36  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 37  
  * 
 38  
  */
 39  
 public class RestServiceDefinition extends AbstractServiceDefinition {
 40  
 
 41  
     private static final long serialVersionUID = 5892163789061959602L;
 42  
 
 43  
         private String resourceClass;
 44  
         transient private List<Object> resources;
 45  
         private BidiMap resourceToClassNameMap;
 46  
         transient private List<Object> providers;
 47  
         transient private Map<Object, Object> extensionMappings;
 48  
         transient private Map<Object, Object> languageMappings;
 49  
 
 50  
         /**
 51  
          * Default constructor.  Sets bus security to FALSE.
 52  
          */
 53  3
         public RestServiceDefinition() {
 54  3
                 setBusSecurity(false);
 55  3
         }
 56  
         
 57  
         @Override
 58  
         public String getType() {
 59  3
                 return KsbApiConstants.ServiceTypes.REST;
 60  
         }
 61  
 
 62  
         /**
 63  
          * To ensure transparency that RESTful services are not digitally signed, throw an exception
 64  
          * if someone tries to enable bus security.
 65  
          *
 66  
          * @see org.kuali.rice.ksb.AbstractServiceDefinition.ServiceDefinition#setBusSecurity(java.lang.Boolean)
 67  
          */
 68  
         @Override
 69  
         public void setBusSecurity(Boolean busSecurity) {
 70  3
             if (busSecurity == true) {
 71  0
                 throw new RiceRuntimeException("Rice does not support bus security (digital request/response signing) " +
 72  
                                 "for RESTful services");
 73  
             }
 74  3
             super.setBusSecurity(busSecurity);
 75  3
         }
 76  
 
 77  
         /**
 78  
          * Set the resourceClass, the class or interface marked by the JAX-WS annotations
 79  
          * which specify the RESTful URL interface.
 80  
          * @param resourceClass the resourceClass to set
 81  
          */
 82  
         public void setResourceClass(String resourceClass) {
 83  2
                 this.resourceClass = resourceClass;
 84  2
         }
 85  
 
 86  
         /**
 87  
          * @see #setResourceClass(String)
 88  
          * @return the resourceClass
 89  
          */
 90  
         public String getResourceClass() {
 91  5
                 return this.resourceClass;
 92  
         }
 93  
 
 94  
         /**
 95  
          * does some simple validation of this RESTServiceDefinition
 96  
          *
 97  
          * @see org.kuali.rice.ksb.AbstractServiceDefinition.ServiceDefinition#validate()
 98  
          */
 99  
         @Override
 100  
         public void validate() {
 101  
 
 102  1
                 List<Object> resources = getResources();
 103  
 
 104  1
                 if (resources != null && !resources.isEmpty()) {
 105  1
                         resourceToClassNameMap = new DualHashBidiMap();
 106  1
                         for (Object resource : resources) {
 107  
                                 // If there is no service set then we have to assume that it's the first resource
 108  2
                                 if (getService() == null) {
 109  1
                                         setService(resource);
 110  
                                 }
 111  
 
 112  2
                                 Class<?> resourceClass = resource.getClass();
 113  2
                                 if (resourceClass != null) {
 114  2
                                         Class<?>[] interfaces = null;
 115  
 
 116  2
                                         if (resourceClass.isInterface()) {
 117  0
                                                 interfaces = new Class[1];
 118  0
                                                 interfaces[0] = resourceClass;
 119  
                                         } else {
 120  2
                                                 interfaces = resourceClass.getInterfaces();
 121  
                                         }
 122  
 
 123  2
                                         if (interfaces != null) {
 124  4
                                                 for (Class<?> iface : interfaces) {
 125  2
                                                         Path pathAnnotation = (Path)iface.getAnnotation(Path.class);
 126  2
                                                         if (pathAnnotation != null) {
 127  1
                                                                 String pathAnnotationValue = pathAnnotation.value();
 128  1
                                                                 String resourceId = pathAnnotationValue == null || pathAnnotationValue.equals("/") ? iface.getSimpleName() : pathAnnotationValue;
 129  1
                                                                 resourceToClassNameMap.put(resourceId, iface.getName());
 130  1
                                                         } else {
 131  
                                                                 // If no path annotation exists, use the simple class name
 132  1
                                                                 resourceToClassNameMap.put(iface.getSimpleName(), iface.getName());
 133  
                                                         }
 134  
                                                 }
 135  
                                         }
 136  
                                 }
 137  2
                         }
 138  
 
 139  
                 }
 140  
                 
 141  1
                 super.validate();
 142  
 
 143  
                 // if interface is null, set it to the service class
 144  1
                 if (getResourceClass() == null) {
 145  1
                         Class<?>[] interfaces = getService().getClass().getInterfaces();
 146  1
                         if (interfaces != null && interfaces.length > 0) {
 147  1
                                 setResourceClass(interfaces[0].getName());
 148  
                         } else {
 149  0
                             throw new ConfigurationException("resource class must be set to export a REST service");
 150  
                         }
 151  
                 }
 152  
 
 153  
                 // Validate that the JAX-WS annotated class / interface is available to the classloader.
 154  
                 try {
 155  1
                     Class.forName(getResourceClass());
 156  0
                 } catch (ClassNotFoundException e) {
 157  0
                     throw new ConfigurationException(
 158  
                             "resource class '" + getResourceClass() + "' could not be found in the classpath");
 159  1
                 }
 160  
 
 161  1
         }
 162  
         
 163  
         @Override
 164  
         protected ServiceConfiguration configure() {
 165  0
                 return RestServiceConfiguration.fromServiceDefinition(this);
 166  
         }
 167  
 
 168  
         /**
 169  
          * @return the resources
 170  
          */
 171  
         public List<Object> getResources() {
 172  1
                 return this.resources;
 173  
         }
 174  
 
 175  
         /**
 176  
          * @param resources the resources to set
 177  
          */
 178  
         public void setResources(List<Object> resources) {
 179  1
                 this.resources = resources;
 180  1
         }
 181  
 
 182  
         /**
 183  
          * @return the resourceToClassNameMap
 184  
          */
 185  
         @SuppressWarnings("unchecked")
 186  
         public Map<String, String> getResourceToClassNameMap() {
 187  4
                 return this.resourceToClassNameMap;
 188  
         }
 189  
 
 190  
         /**
 191  
          * @param className
 192  
          * @return true if this service contains a resource for the given class name
 193  
          */
 194  
         public boolean hasClass(String className) {
 195  0
                 if (resourceToClassNameMap == null) return false;
 196  0
                 return resourceToClassNameMap.containsValue(className);
 197  
         }
 198  
 
 199  
         /**
 200  
          * @return the providers
 201  
          */
 202  
         public List<Object> getProviders() {
 203  0
                 return this.providers;
 204  
         }
 205  
 
 206  
         /**
 207  
          * @param providers the providers to set
 208  
          */
 209  
         public void setProviders(List<Object> providers) {
 210  0
                 this.providers = providers;
 211  0
         }
 212  
 
 213  
         /**
 214  
          * @return the extensionMappings
 215  
          */
 216  
         public Map<Object, Object> getExtensionMappings() {
 217  0
                 return this.extensionMappings;
 218  
         }
 219  
 
 220  
         /**
 221  
          * @param extensionMappings the extensionMappings to set
 222  
          */
 223  
         public void setExtensionMappings(Map<Object, Object> extensionMappings) {
 224  0
                 this.extensionMappings = extensionMappings;
 225  0
         }
 226  
 
 227  
         /**
 228  
          * @return the languageMappings
 229  
          */
 230  
         public Map<Object, Object> getLanguageMappings() {
 231  0
                 return this.languageMappings;
 232  
         }
 233  
 
 234  
         /**
 235  
          * @param languageMappings the languageMappings to set
 236  
          */
 237  
         public void setLanguageMappings(Map<Object, Object> languageMappings) {
 238  0
                 this.languageMappings = languageMappings;
 239  0
         }
 240  
 
 241  
 
 242  
 
 243  
 }