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