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