├── .gitignore ├── README.md └── Texelz └── RESTful ├── META-INF └── MANIFEST.MF ├── config └── com │ └── texelz │ └── atgrestful │ └── NucleusRestPackages.properties ├── lib ├── asm-3.1.jar ├── classes.jar │ ├── com │ │ └── texelz │ │ │ └── atgrestful │ │ │ ├── Nucleus.class │ │ │ ├── NucleusJerseyServlet.class │ │ │ ├── NucleusResourceConfig.class │ │ │ ├── NucleusRestPackages.class │ │ │ ├── core │ │ │ ├── BaseRESTService.class │ │ │ ├── CollectionResource.class │ │ │ ├── Entity.class │ │ │ ├── Link.class │ │ │ └── ResourcePath.class │ │ │ ├── error │ │ │ ├── RestError$Builder.class │ │ │ └── RestError.class │ │ │ ├── example │ │ │ └── RequestService.class │ │ │ ├── exceptions │ │ │ └── UnknownResourceException.class │ │ │ ├── http │ │ │ ├── HttpStatus$Series.class │ │ │ └── HttpStatus.class │ │ │ ├── lang │ │ │ ├── ClassUtils$1.class │ │ │ ├── ClassUtils$2.class │ │ │ ├── ClassUtils$3.class │ │ │ ├── ClassUtils$ClassLoaderAccessor.class │ │ │ ├── ClassUtils$ExceptionIgnoringAccessor.class │ │ │ ├── ClassUtils.class │ │ │ ├── ObjectUtils.class │ │ │ ├── OrderPreservingProperties.class │ │ │ └── StringUtils.class │ │ │ └── providers │ │ │ ├── DefaultExceptionMapper.class │ │ │ ├── NucleusProducer$NucleusInjectable.class │ │ │ └── NucleusProducer.class │ └── rest-errors.properties ├── jackson-core-asl-1.9.2.jar ├── jackson-jaxrs-1.9.2.jar ├── jackson-mapper-asl-1.9.2.jar ├── jackson-xc-1.9.2.jar ├── jersey-client-1.17.1.jar ├── jersey-core-1.17.1.jar ├── jersey-json-1.17.1.jar ├── jersey-server-1.17.1.jar ├── jersey-servlet-1.17.1.jar ├── jettison-1.1.jar └── jsr311-api-1.1.1.jar └── src ├── com └── texelz │ └── atgrestful │ ├── Nucleus.java │ ├── NucleusJerseyServlet.java │ ├── NucleusResourceConfig.java │ ├── NucleusRestPackages.java │ ├── core │ ├── BaseRESTService.java │ ├── CollectionResource.java │ ├── Entity.java │ ├── Link.java │ └── ResourcePath.java │ ├── error │ └── RestError.java │ ├── example │ └── RequestService.java │ ├── exceptions │ └── UnknownResourceException.java │ ├── http │ └── HttpStatus.java │ ├── lang │ ├── ClassUtils.java │ ├── ObjectUtils.java │ ├── OrderPreservingProperties.java │ └── StringUtils.java │ └── providers │ ├── DefaultExceptionMapper.java │ └── NucleusProducer.java └── rest-errors.properties /.gitignore: -------------------------------------------------------------------------------- 1 | # Package Files # 2 | *.war 3 | *.ear 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ATGRESTfull 2 | =========== 3 | 4 | Well, in my opinion native Oracle ATG RESTful API is really deprecated, complicated and strange. So, I created this module. 5 | 6 | An [Oracle ATG](http://www.oracle.com/us/products/applications/commerce/atg/index.html) powered with a great RESTful Framework [Jersey](https://jersey.java.net/). 7 | 8 | How does Oracle ATG RESTful module works? Easy and simple like this: 9 | 10 | ```Java 11 | @Path("/atg-restful") 12 | public class RequestService extends BaseRESTService { 13 | 14 | @Nucleus("/OriginatingRequest") 15 | private HttpServletRequest request; 16 | 17 | @Nucleus("/atg/userprofiling/Profile") 18 | private Profile profile; 19 | 20 | @Nucleus("/atg/commerce/catalog/ProductCatalog") 21 | private Repository repository; 22 | 23 | @GET 24 | @Path("/test") 25 | @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN }) 26 | public Response getExample(@PathParam("name") String name) { 27 | String contextPath = request.getContextPath(); 28 | String profileName = profile.getName(); 29 | String repositoryName = repository.getRepositoryName(); 30 | 31 | Map result = createResult(); 32 | result.put("param", name); 33 | result.put("requestScope", contextPath); 34 | result.put("sessionScope", profileName); 35 | result.put("globalScope", repositoryName); 36 | 37 | return Response.ok(result).build(); 38 | } 39 | } 40 | ``` 41 | 42 | Then, a simple GET on path /atg-restful/test URL, will return a JSON/XML/TXT with a param name value, a request, session ang global scoped component value. 43 | 44 | 45 | How to use it? 46 | =========== 47 | 48 | On your ```MANIFEST.MF``` just require the module ```Texelz.RESTful``` like this: 49 | ``` 50 | ATG-Required: ... Texelz.RESTful ... 51 | ``` 52 | 53 | Then, on your ```web.xml``` file place this code: 54 | 55 | ```XML 56 | 57 | NucleusJerseyREST 58 | com.texelz.atgrestful.NucleusJerseyServlet 59 | 60 | com.sun.jersey.config.property.resourceConfigClass 61 | com.texelz.atgrestful.NucleusResourceConfig 62 | 63 | 64 | com.sun.jersey.api.json.POJOMappingFeature 65 | true 66 | 67 | 1 68 | 69 | 70 | NucleusJerseyREST 71 | /r/* 72 | 73 | ``` 74 | 75 | Jersey works loading a package with ```@Path``` annotated, so, now you just need to configure the component ```/com/texelz/atgrestful/NucleusRestPackages``` like this: 76 | 77 | ```INI 78 | packages+=\ 79 | #you packages... 80 | com.custom.restservices.MyService 81 | ``` 82 | 83 | 84 | 85 | 86 | P.S.: 87 | ===== 88 | 89 | It was used some classes and ideas from [Stormpath - todos-jersey](https://github.com/stormpath/todos-jersey) example :). 90 | 91 | Thanks. 92 | -------------------------------------------------------------------------------- /Texelz/RESTful/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | ATG-Config-Path: config/ 3 | ATG-Required: DAS 4 | ATG-Class-Path: 5 | lib/jsr311-api-1.1.1.jar 6 | lib/asm-3.1.jar 7 | lib/jackson-core-asl-1.9.2.jar 8 | lib/jackson-jaxrs-1.9.2.jar 9 | lib/jackson-mapper-asl-1.9.2.jar 10 | lib/jackson-xc-1.9.2.jar 11 | lib/jersey-client-1.17.1.jar 12 | lib/jersey-core-1.17.1.jar 13 | lib/jersey-json-1.17.1.jar 14 | lib/jersey-server-1.17.1.jar 15 | lib/jersey-servlet-1.17.1.jar 16 | lib/jettison-1.1.jar 17 | lib/classes.jar 18 | 19 | -------------------------------------------------------------------------------- /Texelz/RESTful/config/com/texelz/atgrestful/NucleusRestPackages.properties: -------------------------------------------------------------------------------- 1 | $class=com.texelz.atgrestful.NucleusRestPackages 2 | $scope=global 3 | 4 | packages=com.texelz.atgrestful.providers 5 | -------------------------------------------------------------------------------- /Texelz/RESTful/lib/asm-3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/asm-3.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/Nucleus.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/Nucleus.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/NucleusJerseyServlet.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/NucleusJerseyServlet.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/NucleusResourceConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/NucleusResourceConfig.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/NucleusRestPackages.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/NucleusRestPackages.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/BaseRESTService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/BaseRESTService.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/CollectionResource.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/CollectionResource.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/Entity.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/Entity.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/Link.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/Link.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/ResourcePath.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/core/ResourcePath.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/error/RestError$Builder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/error/RestError$Builder.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/error/RestError.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/error/RestError.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/example/RequestService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/example/RequestService.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/exceptions/UnknownResourceException.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/exceptions/UnknownResourceException.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/http/HttpStatus$Series.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/http/HttpStatus$Series.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/http/HttpStatus.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/http/HttpStatus.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$1.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$2.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$3.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$ClassLoaderAccessor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$ClassLoaderAccessor.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$ExceptionIgnoringAccessor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils$ExceptionIgnoringAccessor.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ClassUtils.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ObjectUtils.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/ObjectUtils.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/OrderPreservingProperties.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/OrderPreservingProperties.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/StringUtils.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/lang/StringUtils.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/providers/DefaultExceptionMapper.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/providers/DefaultExceptionMapper.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/providers/NucleusProducer$NucleusInjectable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/providers/NucleusProducer$NucleusInjectable.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/providers/NucleusProducer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/classes.jar/com/texelz/atgrestful/providers/NucleusProducer.class -------------------------------------------------------------------------------- /Texelz/RESTful/lib/classes.jar/rest-errors.properties: -------------------------------------------------------------------------------- 1 | # 400 2 | IllegalArgumentException = 400 | _exmsg 3 | javax.validation.ValidationException = 400 | _exmsg 4 | atg.droplet.DropletException = 400 | _exmsg 5 | 6 | # 404 7 | UnknownResourceException = 404 | _exmsg 8 | com.sun.jersey.api.NotFoundException = 404 | The specified resource does not exist. | The specified resource does not exist. 9 | 10 | Throwable = 500 -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jackson-core-asl-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jackson-core-asl-1.9.2.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jackson-jaxrs-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jackson-jaxrs-1.9.2.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jackson-mapper-asl-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jackson-mapper-asl-1.9.2.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jackson-xc-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jackson-xc-1.9.2.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jersey-client-1.17.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jersey-client-1.17.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jersey-core-1.17.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jersey-core-1.17.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jersey-json-1.17.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jersey-json-1.17.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jersey-server-1.17.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jersey-server-1.17.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jersey-servlet-1.17.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jersey-servlet-1.17.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jettison-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jettison-1.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/lib/jsr311-api-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onhate/ATGRESTful/9508e0d49d523067402479ef8bc630a08c426d4d/Texelz/RESTful/lib/jsr311-api-1.1.1.jar -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/Nucleus.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * The powefull annotation that will resolve a nucleus component for you 11 | * 12 | * @author Onhate 13 | * 14 | */ 15 | @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.CONSTRUCTOR }) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Documented 18 | public @interface Nucleus { 19 | 20 | String value(); 21 | } -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/NucleusJerseyServlet.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful; 2 | 3 | import com.sun.jersey.spi.container.servlet.ServletContainer; 4 | 5 | /** 6 | * An extension of com.sun.jersey.spi.container.servlet.ServletContainer just 7 | * for future modifications 8 | * 9 | * @author Onhate 10 | * @see com.sun.jersey.spi.container.servlet.ServletContainer 11 | * 12 | */ 13 | public class NucleusJerseyServlet extends ServletContainer { 14 | 15 | private static final long serialVersionUID = -3373297042992971673L; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/NucleusResourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful; 2 | 3 | import atg.nucleus.Nucleus; 4 | 5 | import com.sun.jersey.api.core.PackagesResourceConfig; 6 | 7 | /** 8 | * This class will load listed service classes on Oracle ATG component 9 | * /com/texelz/atgrestful/NucleusRestPackages 10 | * 11 | * @author Onhate 12 | * @see com.sun.jersey.api.core.PackagesResourceConfig 13 | * 14 | */ 15 | public class NucleusResourceConfig extends PackagesResourceConfig { 16 | 17 | private static final String NUCLEUS_PACKAGES_NAME = "/com/texelz/atgrestful/NucleusRestPackages"; 18 | 19 | public NucleusResourceConfig() { 20 | super(getPackagesFromNucleus()); 21 | } 22 | 23 | private static String[] getPackagesFromNucleus() { 24 | Nucleus nucleus = atg.nucleus.Nucleus.getGlobalNucleus(); 25 | NucleusRestPackages restPackages = (NucleusRestPackages) nucleus.resolveName(NUCLEUS_PACKAGES_NAME); 26 | return restPackages.getPackages(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/NucleusRestPackages.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful; 2 | 3 | /** 4 | * Only stores the packages names for {@link NucleusResourceConfig} loading on 5 | * Jersey framework 6 | * 7 | * @author Onhate 8 | * 9 | * @see NucleusResourceConfig 10 | * 11 | */ 12 | public class NucleusRestPackages { 13 | 14 | private String[] packages; 15 | 16 | public void setPackages(String[] packages) { 17 | this.packages = packages; 18 | } 19 | 20 | public String[] getPackages() { 21 | return packages; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/core/BaseRESTService.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.core; 2 | 3 | import java.net.URI; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import javax.ws.rs.core.Response; 8 | 9 | /** 10 | * Some basic operations for a good RESTful service, it's optional extending 11 | * this class for a ATG RESTful service 12 | * 13 | * @author Onhate 14 | * 15 | */ 16 | public abstract class BaseRESTService { 17 | 18 | protected Response created(Link resource) { 19 | String href = (String) resource.get("href"); 20 | URI uri = URI.create(href); 21 | return Response.created(uri).entity(resource).build(); 22 | } 23 | 24 | protected Map createResult() { 25 | return new HashMap(); 26 | } 27 | 28 | protected Map createResult(String key, Object value) { 29 | HashMap result = new HashMap(); 30 | result.put(key, value); 31 | return result; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/core/CollectionResource.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.core; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | 6 | import javax.ws.rs.core.UriInfo; 7 | 8 | /** 9 | * An utility class when loading a Collection of itens, just to not load all 10 | * itens, and paginate on them 11 | * 12 | * @author Onhate 13 | * 14 | */ 15 | public class CollectionResource extends Link { 16 | 17 | private static final long serialVersionUID = 2301157844766660273L; 18 | public static final int DEFAULT_LIMIT = 25; 19 | 20 | public CollectionResource(UriInfo info, String subPath, Collection c) { 21 | this(info, subPath, c, 0, getLimit(c)); 22 | } 23 | 24 | @SuppressWarnings("unchecked") 25 | public CollectionResource(UriInfo info, String subPath, Collection c, int offset, int limit) { 26 | super(info, subPath); 27 | put("offset", offset); 28 | put("limit", getLimit(limit)); 29 | put("items", c != null ? c : Collections.emptyList()); 30 | } 31 | 32 | private static int getLimit(Collection c) { 33 | return getLimit(c != null ? c.size() : 0); 34 | } 35 | 36 | private static int getLimit(int limit) { 37 | return Math.max(DEFAULT_LIMIT, limit); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/core/Entity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Stormpath, Inc. 3 | * 4 | * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 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 com.texelz.atgrestful.core; 17 | 18 | /** 19 | * Base class for all entities in the application. 20 | */ 21 | public abstract class Entity { 22 | 23 | private String id; 24 | 25 | public Entity() { 26 | } 27 | 28 | public String getId() { 29 | return id; 30 | } 31 | 32 | public void setId(String id) { 33 | this.id = id; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/core/Link.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.core; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | import javax.ws.rs.core.UriInfo; 6 | 7 | /** 8 | * All resources are a potential Link ;) 9 | * 10 | * @author Onhate 11 | * 12 | */ 13 | @SuppressWarnings({ "unchecked", "rawtypes" }) 14 | public class Link extends LinkedHashMap { 15 | 16 | private static final long serialVersionUID = 6138089806561712431L; 17 | 18 | public static final String PATH_SEPARATOR = "/"; 19 | 20 | public Link(UriInfo info, Entity entity) { 21 | this(getFullyQualifiedContextPath(info), entity); 22 | } 23 | 24 | public Link(String fqBasePath, Entity entity) { 25 | String href = createHref(fqBasePath, entity); 26 | put("href", href); 27 | } 28 | 29 | public Link(UriInfo info, String subPath) { 30 | this(getFullyQualifiedContextPath(info), subPath); 31 | } 32 | 33 | public Link(String fqBasePath, String subPath) { 34 | String href = fqBasePath + subPath; 35 | put("href", href); 36 | } 37 | 38 | protected static String getFullyQualifiedContextPath(UriInfo info) { 39 | String fq = info.getBaseUri().toString(); 40 | if (fq.endsWith("/")) { 41 | return fq.substring(0, fq.length() - 1); 42 | } 43 | return fq; 44 | } 45 | 46 | protected String createHref(String fqBasePath, Entity entity) { 47 | StringBuilder sb = new StringBuilder(fqBasePath); 48 | String path = ResourcePath.forClass(entity.getClass()); 49 | sb.append(path).append(PATH_SEPARATOR).append(entity.getId()); 50 | return sb.toString(); 51 | } 52 | 53 | public String getHref() { 54 | return (String) get("href"); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/core/ResourcePath.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.core; 2 | 3 | import javax.ws.rs.Path; 4 | 5 | /** 6 | * How to load the path of a Resource URL of a (Class)? Using {@link Path} 7 | * annotation, of course! 8 | * 9 | * @author Onhate 10 | * 11 | */ 12 | public final class ResourcePath { 13 | 14 | /** 15 | * Given a Class, returns the resource path on {@link Path} value 16 | * 17 | * @param clazz 18 | * @return 19 | */ 20 | public static String forClass(Class clazz) { 21 | String result = null; 22 | Path path = clazz.getAnnotation(Path.class); 23 | result = path.value(); 24 | return result; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/error/RestError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Stormpath, Inc. 3 | * 4 | * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 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 com.texelz.atgrestful.error; 17 | 18 | import java.util.LinkedHashMap; 19 | import java.util.Map; 20 | 21 | import com.texelz.atgrestful.http.HttpStatus; 22 | import com.texelz.atgrestful.lang.ObjectUtils; 23 | 24 | /** 25 | * 26 | * @author Onhate 27 | * 28 | */ 29 | public class RestError { 30 | 31 | private static final String STATUS_PROP_NAME = "status"; 32 | private static final String CODE_PROP_NAME = "code"; 33 | private static final String MESSAGE_PROP_NAME = "message"; 34 | private static final String DEVELOPER_MESSAGE_PROP_NAME = "developerMessage"; 35 | 36 | private final HttpStatus status; 37 | private final int code; 38 | private final String message; 39 | private final String developerMessage; 40 | private final Throwable throwable; 41 | 42 | public RestError(HttpStatus status, int code, String message, String developerMessage, Throwable throwable) { 43 | if (status == null) { 44 | throw new NullPointerException("HttpStatus argument cannot be null."); 45 | } 46 | this.status = status; 47 | this.code = code; 48 | this.message = message; 49 | this.developerMessage = developerMessage; 50 | this.throwable = throwable; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) { 56 | return true; 57 | } 58 | if (o instanceof RestError) { 59 | RestError re = (RestError) o; 60 | return ObjectUtils.nullSafeEquals(getStatus(), re.getStatus()) 61 | && ObjectUtils.nullSafeEquals(getCode(), re.getCode()) 62 | && ObjectUtils.nullSafeEquals(getMessage(), re.getMessage()) 63 | && ObjectUtils.nullSafeEquals(getDeveloperMessage(), re.getDeveloperMessage()) 64 | && ObjectUtils.nullSafeEquals(getThrowable(), re.getThrowable()); 65 | 66 | } 67 | return false; 68 | } 69 | 70 | @Override 71 | public int hashCode() { 72 | return ObjectUtils 73 | .nullSafeHashCode(getStatus(), getCode(), getMessage(), getDeveloperMessage(), getThrowable()); 74 | } 75 | 76 | public String toString() { 77 | return append(new StringBuilder(), getStatus()).append(", message: ").append(getMessage()).toString(); 78 | } 79 | 80 | private StringBuilder append(StringBuilder buf, HttpStatus status) { 81 | buf.append(status.value()).append(" (").append(status.getReasonPhrase()).append(")"); 82 | return buf; 83 | } 84 | 85 | private String toString(HttpStatus status) { 86 | return append(new StringBuilder(), status).toString(); 87 | } 88 | 89 | public HttpStatus getStatus() { 90 | return status; 91 | } 92 | 93 | public int getCode() { 94 | return code; 95 | } 96 | 97 | public String getMessage() { 98 | return message; 99 | } 100 | 101 | public String getDeveloperMessage() { 102 | return developerMessage; 103 | } 104 | 105 | public Throwable getThrowable() { 106 | return throwable; 107 | } 108 | 109 | public Map toMap() { 110 | Map m = new LinkedHashMap(); 111 | HttpStatus status = getStatus(); 112 | m.put(STATUS_PROP_NAME, status.value()); 113 | 114 | int code = getCode(); 115 | if (code <= 0) { 116 | code = status.value(); 117 | } 118 | m.put(CODE_PROP_NAME, code); 119 | 120 | String httpStatusMessage = null; 121 | 122 | String message = getMessage(); 123 | if (message == null) { 124 | httpStatusMessage = toString(status); 125 | message = httpStatusMessage; 126 | } 127 | m.put(MESSAGE_PROP_NAME, message); 128 | 129 | String devMsg = getDeveloperMessage(); 130 | if (devMsg == null) { 131 | if (httpStatusMessage == null) { 132 | httpStatusMessage = toString(status); 133 | } 134 | devMsg = httpStatusMessage; 135 | 136 | Throwable t = getThrowable(); 137 | if (t != null) { 138 | devMsg = devMsg + ": " + t.getMessage(); 139 | } 140 | } 141 | m.put(DEVELOPER_MESSAGE_PROP_NAME, devMsg); 142 | 143 | return m; 144 | } 145 | 146 | public static class Builder { 147 | 148 | private HttpStatus status; 149 | private int code; 150 | private String message; 151 | private String developerMessage; 152 | private Throwable throwable; 153 | 154 | public Builder() { 155 | } 156 | 157 | public Builder setStatus(int statusCode) { 158 | this.status = HttpStatus.valueOf(statusCode); 159 | return this; 160 | } 161 | 162 | public Builder setStatus(HttpStatus status) { 163 | this.status = status; 164 | return this; 165 | } 166 | 167 | public Builder setCode(int code) { 168 | this.code = code; 169 | return this; 170 | } 171 | 172 | public Builder setMessage(String message) { 173 | this.message = message; 174 | return this; 175 | } 176 | 177 | public Builder setDeveloperMessage(String developerMessage) { 178 | this.developerMessage = developerMessage; 179 | return this; 180 | } 181 | 182 | public Builder setThrowable(Throwable throwable) { 183 | this.throwable = throwable; 184 | return this; 185 | } 186 | 187 | public RestError build() { 188 | if (this.status == null) { 189 | this.status = HttpStatus.INTERNAL_SERVER_ERROR; 190 | } 191 | return new RestError(this.status, this.code, this.message, this.developerMessage, this.throwable); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/example/RequestService.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.example; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.ws.rs.GET; 5 | import javax.ws.rs.Path; 6 | import javax.ws.rs.PathParam; 7 | import javax.ws.rs.Produces; 8 | import javax.ws.rs.core.MediaType; 9 | import javax.ws.rs.core.Response; 10 | 11 | import com.texelz.atgrestful.Nucleus; 12 | import com.texelz.atgrestful.core.BaseRESTService; 13 | 14 | @Path("/atg-restful") 15 | public class RequestService extends BaseRESTService { 16 | 17 | @Nucleus("/OriginatingRequest") 18 | private HttpServletRequest request; 19 | 20 | @GET 21 | @Path("/test") 22 | @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_ATOM_XML, MediaType.TEXT_PLAIN }) 23 | public Response getContextPathWithHello(@PathParam("name") String name) { 24 | String contextPath = request.getContextPath(); 25 | String result = String.format("Hello %s, here it goes: %s ;)", name, contextPath); 26 | 27 | return Response.ok(createResult("result", result)).build(); 28 | } 29 | } -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/exceptions/UnknownResourceException.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.exceptions; 2 | 3 | public class UnknownResourceException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = -3867718498690715709L; 6 | 7 | public UnknownResourceException() { 8 | super(); // To change body of overridden methods use File | Settings | 9 | // File Templates. 10 | } 11 | 12 | public UnknownResourceException(String s) { 13 | super(s); // To change body of overridden methods use File | Settings | 14 | // File Templates. 15 | } 16 | 17 | public UnknownResourceException(String s, Throwable throwable) { 18 | super(s, throwable); // To change body of overridden methods use File | 19 | // Settings | File Templates. 20 | } 21 | 22 | public UnknownResourceException(Throwable throwable) { 23 | super(throwable); // To change body of overridden methods use File | 24 | // Settings | File Templates. 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/http/HttpStatus.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.http; 2 | 3 | /** 4 | * Java 5 enumeration of HTTP status codes. 5 | * 6 | *

7 | * The HTTP status code series can be retrieved via {@link #series()}. 8 | * 9 | * @author Arjen Poutsma 10 | * @see HttpStatus.Series 11 | * @see HTTP Status 12 | * Code Registry 13 | */ 14 | public enum HttpStatus { 15 | 16 | // 1xx Informational 17 | 18 | /** 19 | * {@code 100 Continue}. 20 | * 21 | * @see HTTP/1.1 23 | */ 24 | CONTINUE(100, "Continue"), 25 | /** 26 | * {@code 101 Switching Protocols}. 27 | * 28 | * @see HTTP/1.1 30 | */ 31 | SWITCHING_PROTOCOLS(101, "Switching Protocols"), 32 | /** 33 | * {@code 102 Processing}. 34 | * 35 | * @see WebDAV 36 | */ 37 | PROCESSING(102, "Processing"), 38 | 39 | // 2xx Success 40 | 41 | /** 42 | * {@code 200 OK}. 43 | * 44 | * @see HTTP/1.1 46 | */ 47 | OK(200, "OK"), 48 | /** 49 | * {@code 201 Created}. 50 | * 51 | * @see HTTP/1.1 53 | */ 54 | CREATED(201, "Created"), 55 | /** 56 | * {@code 202 Accepted}. 57 | * 58 | * @see HTTP/1.1 60 | */ 61 | ACCEPTED(202, "Accepted"), 62 | /** 63 | * {@code 203 Non-Authoritative Information}. 64 | * 65 | * @see HTTP/1.1 67 | */ 68 | NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"), 69 | /** 70 | * {@code 204 No Content}. 71 | * 72 | * @see HTTP/1.1 74 | */ 75 | NO_CONTENT(204, "No Content"), 76 | /** 77 | * {@code 205 Reset Content}. 78 | * 79 | * @see HTTP/1.1 81 | */ 82 | RESET_CONTENT(205, "Reset Content"), 83 | /** 84 | * {@code 206 Partial Content}. 85 | * 86 | * @see HTTP/1.1 88 | */ 89 | PARTIAL_CONTENT(206, "Partial Content"), 90 | /** 91 | * {@code 207 Multi-Status}. 92 | * 93 | * @see WebDAV 94 | */ 95 | MULTI_STATUS(207, "Multi-Status"), 96 | /** 97 | * {@code 208 Already Reported}. 98 | * 99 | * @see WebDAV 101 | * Binding Extensions 102 | */ 103 | ALREADY_REPORTED(208, "Already Reported"), 104 | /** 105 | * {@code 226 IM Used}. 106 | * 107 | * @see Delta 108 | * encoding in HTTP 109 | */ 110 | IM_USED(226, "IM Used"), 111 | 112 | // 3xx Redirection 113 | 114 | /** 115 | * {@code 300 Multiple Choices}. 116 | * 117 | * @see HTTP/1.1 119 | */ 120 | MULTIPLE_CHOICES(300, "Multiple Choices"), 121 | /** 122 | * {@code 301 Moved Permanently}. 123 | * 124 | * @see HTTP/1.1 126 | */ 127 | MOVED_PERMANENTLY(301, "Moved Permanently"), 128 | /** 129 | * {@code 302 Found}. 130 | * 131 | * @see HTTP/1.1 133 | */ 134 | FOUND(302, "Found"), 135 | /** 136 | * {@code 302 Moved Temporarily}. 137 | * 138 | * @see HTTP/1.0 140 | */ 141 | MOVED_TEMPORARILY(302, "Moved Temporarily"), 142 | /** 143 | * {@code 303 See Other}. 144 | * 145 | * @see HTTP/1.1 147 | */ 148 | SEE_OTHER(303, "See Other"), 149 | /** 150 | * {@code 304 Not Modified}. 151 | * 152 | * @see HTTP/1.1 154 | */ 155 | NOT_MODIFIED(304, "Not Modified"), 156 | /** 157 | * {@code 305 Use Proxy}. 158 | * 159 | * @see HTTP/1.1 161 | */ 162 | USE_PROXY(305, "Use Proxy"), 163 | /** 164 | * {@code 307 Temporary Redirect}. 165 | * 166 | * @see HTTP/1.1 168 | */ 169 | TEMPORARY_REDIRECT(307, "Temporary Redirect"), 170 | 171 | // --- 4xx Client Error --- 172 | 173 | /** 174 | * {@code 400 Bad Request}. 175 | * 176 | * @see HTTP/1.1 178 | */ 179 | BAD_REQUEST(400, "Bad Request"), 180 | /** 181 | * {@code 401 Unauthorized}. 182 | * 183 | * @see HTTP/1.1 185 | */ 186 | UNAUTHORIZED(401, "Unauthorized"), 187 | /** 188 | * {@code 402 Payment Required}. 189 | * 190 | * @see HTTP/1.1 192 | */ 193 | PAYMENT_REQUIRED(402, "Payment Required"), 194 | /** 195 | * {@code 403 Forbidden}. 196 | * 197 | * @see HTTP/1.1 199 | */ 200 | FORBIDDEN(403, "Forbidden"), 201 | /** 202 | * {@code 404 Not Found}. 203 | * 204 | * @see HTTP/1.1 206 | */ 207 | NOT_FOUND(404, "Not Found"), 208 | /** 209 | * {@code 405 Method Not Allowed}. 210 | * 211 | * @see HTTP/1.1 213 | */ 214 | METHOD_NOT_ALLOWED(405, "Method Not Allowed"), 215 | /** 216 | * {@code 406 Not Acceptable}. 217 | * 218 | * @see HTTP/1.1 220 | */ 221 | NOT_ACCEPTABLE(406, "Not Acceptable"), 222 | /** 223 | * {@code 407 Proxy Authentication Required}. 224 | * 225 | * @see HTTP/1.1 227 | */ 228 | PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"), 229 | /** 230 | * {@code 408 Request Timeout}. 231 | * 232 | * @see HTTP/1.1 234 | */ 235 | REQUEST_TIMEOUT(408, "Request Time-out"), 236 | /** 237 | * {@code 409 Conflict}. 238 | * 239 | * @see HTTP/1.1 241 | */ 242 | CONFLICT(409, "Conflict"), 243 | /** 244 | * {@code 410 Gone}. 245 | * 246 | * @see HTTP/1.1 248 | */ 249 | GONE(410, "Gone"), 250 | /** 251 | * {@code 411 Length Required}. 252 | * 253 | * @see HTTP/1.1 255 | */ 256 | LENGTH_REQUIRED(411, "Length Required"), 257 | /** 258 | * {@code 412 Precondition failed}. 259 | * 260 | * @see HTTP/1.1 262 | */ 263 | PRECONDITION_FAILED(412, "Precondition Failed"), 264 | /** 265 | * {@code 413 Request Entity Too Large}. 266 | * 267 | * @see HTTP/1.1 269 | */ 270 | REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"), 271 | /** 272 | * {@code 414 Request-URI Too Long}. 273 | * 274 | * @see HTTP/1.1 276 | */ 277 | REQUEST_URI_TOO_LONG(414, "Request-URI Too Large"), 278 | /** 279 | * {@code 415 Unsupported Media Type}. 280 | * 281 | * @see HTTP/1.1 283 | */ 284 | UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"), 285 | /** 286 | * {@code 416 Requested Range Not Satisfiable}. 287 | * 288 | * @see HTTP/1.1 290 | */ 291 | REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested range not satisfiable"), 292 | /** 293 | * {@code 417 Expectation Failed}. 294 | * 295 | * @see HTTP/1.1 297 | */ 298 | EXPECTATION_FAILED(417, "Expectation Failed"), 299 | /** 300 | * {@code 419 Insufficient Space on Resource}. 301 | * 302 | * @see WebDAV 304 | * Draft 305 | */ 306 | INSUFFICIENT_SPACE_ON_RESOURCE(419, "Insufficient Space On Resource"), 307 | /** 308 | * {@code 420 Method Failure}. 309 | * 310 | * @see WebDAV 312 | * Draft 313 | */ 314 | METHOD_FAILURE(420, "Method Failure"), 315 | /** 316 | * {@code 421 Destination Locked}. 317 | * 318 | * @see WebDAV 320 | * Draft 321 | */ 322 | DESTINATION_LOCKED(421, "Destination Locked"), 323 | /** 324 | * {@code 422 Unprocessable Entity}. 325 | * 326 | * @see WebDAV 327 | */ 328 | UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"), 329 | /** 330 | * {@code 423 Locked}. 331 | * 332 | * @see WebDAV 333 | */ 334 | LOCKED(423, "Locked"), 335 | /** 336 | * {@code 424 Failed Dependency}. 337 | * 338 | * @see WebDAV 339 | */ 340 | FAILED_DEPENDENCY(424, "Failed Dependency"), 341 | /** 342 | * {@code 426 Upgrade Required}. 343 | * 344 | * @see Upgrading to 345 | * TLS Within HTTP/1.1 346 | */ 347 | UPGRADE_REQUIRED(426, "Upgrade Required"), 348 | 349 | // --- 5xx Server Error --- 350 | 351 | /** 352 | * {@code 500 Internal Server Error}. 353 | * 354 | * @see HTTP/1.1 356 | */ 357 | INTERNAL_SERVER_ERROR(500, "Internal Server Error"), 358 | /** 359 | * {@code 501 Not Implemented}. 360 | * 361 | * @see HTTP/1.1 363 | */ 364 | NOT_IMPLEMENTED(501, "Not Implemented"), 365 | /** 366 | * {@code 502 Bad Gateway}. 367 | * 368 | * @see HTTP/1.1 370 | */ 371 | BAD_GATEWAY(502, "Bad Gateway"), 372 | /** 373 | * {@code 503 Service Unavailable}. 374 | * 375 | * @see HTTP/1.1 377 | */ 378 | SERVICE_UNAVAILABLE(503, "Service Unavailable"), 379 | /** 380 | * {@code 504 Gateway Timeout}. 381 | * 382 | * @see HTTP/1.1 384 | */ 385 | GATEWAY_TIMEOUT(504, "Gateway Time-out"), 386 | /** 387 | * {@code 505 HTTP Version Not Supported}. 388 | * 389 | * @see HTTP/1.1 391 | */ 392 | HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version not supported"), 393 | /** 394 | * {@code 506 Variant Also Negotiates} 395 | * 396 | * @see Transparent 397 | * Content Negotiation 398 | */ 399 | VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates"), 400 | /** 401 | * {@code 507 Insufficient Storage} 402 | * 403 | * @see WebDAV 404 | */ 405 | INSUFFICIENT_STORAGE(507, "Insufficient Storage"), 406 | /** 407 | * {@code 508 Loop Detected} 408 | * 409 | * @see WebDAV 411 | * Binding Extensions 412 | */ 413 | LOOP_DETECTED(508, "Loop Detected"), 414 | /** 415 | * {@code 510 Not Extended} 416 | * 417 | * @see HTTP 418 | * Extension Framework 419 | */ 420 | NOT_EXTENDED(510, "Not Extended"); 421 | 422 | private final int value; 423 | 424 | private final String reasonPhrase; 425 | 426 | private HttpStatus(int value, String reasonPhrase) { 427 | this.value = value; 428 | this.reasonPhrase = reasonPhrase; 429 | } 430 | 431 | /** 432 | * Return the integer value of this status code. 433 | */ 434 | public int value() { 435 | return this.value; 436 | } 437 | 438 | /** 439 | * Return the reason phrase of this status code. 440 | */ 441 | public String getReasonPhrase() { 442 | return reasonPhrase; 443 | } 444 | 445 | /** 446 | * Returns the HTTP status series of this status code. 447 | * 448 | * @see HttpStatus.Series 449 | */ 450 | public Series series() { 451 | return Series.valueOf(this); 452 | } 453 | 454 | /** 455 | * Return a string representation of this status code. 456 | */ 457 | @Override 458 | public String toString() { 459 | return Integer.toString(value); 460 | } 461 | 462 | /** 463 | * Return the enum constant of this type with the specified numeric value. 464 | * 465 | * @param statusCode 466 | * the numeric value of the enum to be returned 467 | * @return the enum constant with the specified numeric value 468 | * @throws IllegalArgumentException 469 | * if this enum has no constant for the specified numeric value 470 | */ 471 | public static HttpStatus valueOf(int statusCode) { 472 | for (HttpStatus status : values()) { 473 | if (status.value == statusCode) { 474 | return status; 475 | } 476 | } 477 | throw new IllegalArgumentException("No matching constant for [" + statusCode + "]"); 478 | } 479 | 480 | /** 481 | * Java 5 enumeration of HTTP status series. 482 | *

483 | * Retrievable via {@link HttpStatus#series()}. 484 | */ 485 | public static enum Series { 486 | 487 | INFORMATIONAL(1), SUCCESSFUL(2), REDIRECTION(3), CLIENT_ERROR(4), SERVER_ERROR(5); 488 | 489 | private final int value; 490 | 491 | private Series(int value) { 492 | this.value = value; 493 | } 494 | 495 | /** 496 | * Return the integer value of this status series. Ranges from 1 to 5. 497 | */ 498 | public int value() { 499 | return this.value; 500 | } 501 | 502 | private static Series valueOf(HttpStatus status) { 503 | int seriesCode = status.value() / 100; 504 | for (Series series : values()) { 505 | if (series.value == seriesCode) { 506 | return series; 507 | } 508 | } 509 | throw new IllegalArgumentException("No matching constant for [" + status + "]"); 510 | } 511 | 512 | } 513 | 514 | } 515 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/lang/ClassUtils.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.lang; 2 | 3 | import java.io.InputStream; 4 | import java.lang.reflect.Constructor; 5 | 6 | public class ClassUtils { 7 | 8 | /** 9 | * @since 1.0 10 | */ 11 | private static final ClassLoaderAccessor THREAD_CL_ACCESSOR = new ExceptionIgnoringAccessor() { 12 | @Override 13 | protected ClassLoader doGetClassLoader() throws Throwable { 14 | return Thread.currentThread().getContextClassLoader(); 15 | } 16 | }; 17 | 18 | /** 19 | * @since 1.0 20 | */ 21 | private static final ClassLoaderAccessor CLASS_CL_ACCESSOR = new ExceptionIgnoringAccessor() { 22 | @Override 23 | protected ClassLoader doGetClassLoader() throws Throwable { 24 | return ClassUtils.class.getClassLoader(); 25 | } 26 | }; 27 | 28 | /** 29 | * @since 1.0 30 | */ 31 | private static final ClassLoaderAccessor SYSTEM_CL_ACCESSOR = new ExceptionIgnoringAccessor() { 32 | @Override 33 | protected ClassLoader doGetClassLoader() throws Throwable { 34 | return ClassLoader.getSystemClassLoader(); 35 | } 36 | }; 37 | 38 | /** 39 | * Returns the specified resource by checking the current thread's 40 | * {@link Thread#getContextClassLoader() context class loader}, then the 41 | * current ClassLoader (ClassUtils.class.getClassLoader()), 42 | * then the system/application ClassLoader ( 43 | * ClassLoader.getSystemClassLoader(), in that order, using 44 | * {@link ClassLoader#getResourceAsStream(String) getResourceAsStream(name)} 45 | * . 46 | * 47 | * @param name 48 | * the name of the resource to acquire from the classloader(s). 49 | * @return the InputStream of the resource found, or null if 50 | * the resource cannot be found from any of the three mentioned 51 | * ClassLoaders. 52 | * @since 0.9 53 | */ 54 | public static InputStream getResourceAsStream(String name) { 55 | InputStream is = THREAD_CL_ACCESSOR.getResourceStream(name); 56 | if (is == null) { 57 | is = CLASS_CL_ACCESSOR.getResourceStream(name); 58 | } 59 | if (is == null) { 60 | is = SYSTEM_CL_ACCESSOR.getResourceStream(name); 61 | } 62 | return is; 63 | } 64 | 65 | /** 66 | * Attempts to load the specified class name from the current thread's 67 | * {@link Thread#getContextClassLoader() context class loader}, then the 68 | * current ClassLoader (ClassUtils.class.getClassLoader()), 69 | * then the system/application ClassLoader ( 70 | * ClassLoader.getSystemClassLoader(), in that order. If any of 71 | * them cannot locate the specified class, an 72 | * UnknownClassException is thrown (our RuntimeException 73 | * equivalent of the JRE's ClassNotFoundException. 74 | * 75 | * @param fqcn 76 | * the fully qualified class name to load 77 | * @return the located class 78 | */ 79 | @SuppressWarnings("rawtypes") 80 | public static Class forName(String fqcn) throws RuntimeException { 81 | Class clazz = THREAD_CL_ACCESSOR.loadClass(fqcn); 82 | if (clazz == null) { 83 | clazz = CLASS_CL_ACCESSOR.loadClass(fqcn); 84 | } 85 | if (clazz == null) { 86 | clazz = SYSTEM_CL_ACCESSOR.loadClass(fqcn); 87 | } 88 | 89 | if (clazz == null) { 90 | String msg = "Unable to load class named [" 91 | + fqcn 92 | + "] from the thread context, current, or " 93 | + "system/application ClassLoaders. All heuristics have been exhausted. Class could not be found."; 94 | throw new RuntimeException(msg); 95 | } 96 | 97 | return clazz; 98 | } 99 | 100 | public static boolean isAvailable(String fullyQualifiedClassName) { 101 | try { 102 | forName(fullyQualifiedClassName); 103 | return true; 104 | } catch (RuntimeException e) { 105 | return false; 106 | } 107 | } 108 | 109 | public static Object newInstance(String fqcn) { 110 | return newInstance(forName(fqcn)); 111 | } 112 | 113 | public static Object newInstance(String fqcn, Object... args) { 114 | return newInstance(forName(fqcn), args); 115 | } 116 | 117 | @SuppressWarnings("rawtypes") 118 | public static Object newInstance(Class clazz) { 119 | if (clazz == null) { 120 | String msg = "Class method parameter cannot be null."; 121 | throw new IllegalArgumentException(msg); 122 | } 123 | try { 124 | return clazz.newInstance(); 125 | } catch (Exception e) { 126 | throw new RuntimeException("Unable to instantiate class [" + clazz.getName() + "]", e); 127 | } 128 | } 129 | 130 | @SuppressWarnings("rawtypes") 131 | public static Object newInstance(Class clazz, Object... args) { 132 | Class[] argTypes = new Class[args.length]; 133 | for (int i = 0; i < args.length; i++) { 134 | argTypes[i] = args[i].getClass(); 135 | } 136 | Constructor ctor = getConstructor(clazz, argTypes); 137 | return instantiate(ctor, args); 138 | } 139 | 140 | @SuppressWarnings({ "rawtypes", "unchecked" }) 141 | public static Constructor getConstructor(Class clazz, Class... argTypes) { 142 | try { 143 | return clazz.getConstructor(argTypes); 144 | } catch (NoSuchMethodException e) { 145 | throw new IllegalStateException(e); 146 | } 147 | 148 | } 149 | 150 | @SuppressWarnings("rawtypes") 151 | public static Object instantiate(Constructor ctor, Object... args) { 152 | try { 153 | return ctor.newInstance(args); 154 | } catch (Exception e) { 155 | String msg = "Unable to instantiate Permission instance with constructor [" + ctor + "]"; 156 | throw new RuntimeException(msg, e); 157 | } 158 | } 159 | 160 | /** 161 | * @since 1.0 162 | */ 163 | @SuppressWarnings("rawtypes") 164 | private static interface ClassLoaderAccessor { 165 | Class loadClass(String fqcn); 166 | 167 | InputStream getResourceStream(String name); 168 | } 169 | 170 | /** 171 | * @since 1.0 172 | */ 173 | private static abstract class ExceptionIgnoringAccessor implements ClassLoaderAccessor { 174 | 175 | @SuppressWarnings("rawtypes") 176 | public Class loadClass(String fqcn) { 177 | Class clazz = null; 178 | ClassLoader cl = getClassLoader(); 179 | if (cl != null) { 180 | try { 181 | clazz = cl.loadClass(fqcn); 182 | } catch (ClassNotFoundException e) { 183 | } 184 | } 185 | return clazz; 186 | } 187 | 188 | public InputStream getResourceStream(String name) { 189 | InputStream is = null; 190 | ClassLoader cl = getClassLoader(); 191 | if (cl != null) { 192 | is = cl.getResourceAsStream(name); 193 | } 194 | return is; 195 | } 196 | 197 | protected final ClassLoader getClassLoader() { 198 | try { 199 | return doGetClassLoader(); 200 | } catch (Throwable t) { 201 | } 202 | return null; 203 | } 204 | 205 | protected abstract ClassLoader doGetClassLoader() throws Throwable; 206 | } 207 | 208 | } 209 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/lang/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.lang; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Various object utility methods. 7 | */ 8 | public class ObjectUtils { 9 | 10 | public static final int INITIAL_HASH = 7; 11 | public static final int MULTIPLIER = 31; 12 | 13 | /** 14 | * Return the same value as {@link Boolean#hashCode()}. 15 | * 16 | * @param b 17 | * the boolean to hash. 18 | * @return the same value as {@link Boolean#hashCode()}. 19 | * @see Boolean#hashCode() 20 | */ 21 | public static int hashCode(boolean b) { 22 | return b ? 1231 : 1237; 23 | } 24 | 25 | /** 26 | * Return the same value as {@link Double#hashCode()}. 27 | * 28 | * @param dbl 29 | * the double to hash 30 | * @return the same value as {@link Double#hashCode()} 31 | * @see Double#hashCode() 32 | */ 33 | public static int hashCode(double dbl) { 34 | long bits = Double.doubleToLongBits(dbl); 35 | return hashCode(bits); 36 | } 37 | 38 | /** 39 | * Return the same value as {@link Float#hashCode()}. 40 | * 41 | * @param flt 42 | * the float to hash 43 | * @return the save value as {@link Float#hashCode()}. 44 | * @see Float#hashCode() 45 | */ 46 | public static int hashCode(float flt) { 47 | return Float.floatToIntBits(flt); 48 | } 49 | 50 | /** 51 | * Return the same value as {@link Long#hashCode()}. 52 | * 53 | * @param l 54 | * the long to hash 55 | * @return the same value as {@link Long#hashCode()}. 56 | * @see Long#hashCode() 57 | */ 58 | public static int hashCode(long l) { 59 | return (int) (l ^ (l >>> 32)); 60 | } 61 | 62 | /** 63 | * Determine if the given objects are equal, returning true if 64 | * both are null or false if only one is 65 | * null. 66 | *

67 | * Compares arrays with Arrays.equals, performing an equality 68 | * check based on the array elements rather than the array reference. 69 | * 70 | * @param o1 71 | * first Object to compare 72 | * @param o2 73 | * second Object to compare 74 | * @return whether the given objects are equal 75 | * @see java.util.Arrays#equals 76 | */ 77 | public static boolean nullSafeEquals(Object o1, Object o2) { 78 | if (o1 == o2) { 79 | return true; 80 | } 81 | if (o1 == null || o2 == null) { 82 | return false; 83 | } 84 | if (o1.equals(o2)) { 85 | return true; 86 | } 87 | if (o1.getClass().isArray() && o2.getClass().isArray()) { 88 | if (o1 instanceof Object[] && o2 instanceof Object[]) { 89 | return Arrays.equals((Object[]) o1, (Object[]) o2); 90 | } 91 | if (o1 instanceof boolean[] && o2 instanceof boolean[]) { 92 | return Arrays.equals((boolean[]) o1, (boolean[]) o2); 93 | } 94 | if (o1 instanceof byte[] && o2 instanceof byte[]) { 95 | return Arrays.equals((byte[]) o1, (byte[]) o2); 96 | } 97 | if (o1 instanceof char[] && o2 instanceof char[]) { 98 | return Arrays.equals((char[]) o1, (char[]) o2); 99 | } 100 | if (o1 instanceof double[] && o2 instanceof double[]) { 101 | return Arrays.equals((double[]) o1, (double[]) o2); 102 | } 103 | if (o1 instanceof float[] && o2 instanceof float[]) { 104 | return Arrays.equals((float[]) o1, (float[]) o2); 105 | } 106 | if (o1 instanceof int[] && o2 instanceof int[]) { 107 | return Arrays.equals((int[]) o1, (int[]) o2); 108 | } 109 | if (o1 instanceof long[] && o2 instanceof long[]) { 110 | return Arrays.equals((long[]) o1, (long[]) o2); 111 | } 112 | if (o1 instanceof short[] && o2 instanceof short[]) { 113 | return Arrays.equals((short[]) o1, (short[]) o2); 114 | } 115 | } 116 | return false; 117 | } 118 | 119 | /** 120 | * Return as hash code for the given object; typically the value of 121 | * {@link Object#hashCode()}. If the object is an array, this 122 | * method will delegate to any of the nullSafeHashCode methods 123 | * for arrays in this class. If the object is null, this method 124 | * returns 0. 125 | * 126 | * @param obj 127 | * the object for which to generate a hash code. 128 | * @return the hash code, or {@code 0} if the object is null. 129 | * @see #nullSafeHashCode(Object...) 130 | * @see #nullSafeHashCode(boolean[]) 131 | * @see #nullSafeHashCode(byte[]) 132 | * @see #nullSafeHashCode(char[]) 133 | * @see #nullSafeHashCode(double[]) 134 | * @see #nullSafeHashCode(float[]) 135 | * @see #nullSafeHashCode(int[]) 136 | * @see #nullSafeHashCode(long[]) 137 | * @see #nullSafeHashCode(short[]) 138 | */ 139 | public static int nullSafeHashCode(Object obj) { 140 | if (obj == null) { 141 | return 0; 142 | } 143 | if (obj.getClass().isArray()) { 144 | if (obj instanceof Object[]) { 145 | return nullSafeHashCode((Object[]) obj); 146 | } 147 | if (obj instanceof boolean[]) { 148 | return nullSafeHashCode((boolean[]) obj); 149 | } 150 | if (obj instanceof byte[]) { 151 | return nullSafeHashCode((byte[]) obj); 152 | } 153 | if (obj instanceof char[]) { 154 | return nullSafeHashCode((char[]) obj); 155 | } 156 | if (obj instanceof double[]) { 157 | return nullSafeHashCode((double[]) obj); 158 | } 159 | if (obj instanceof float[]) { 160 | return nullSafeHashCode((float[]) obj); 161 | } 162 | if (obj instanceof int[]) { 163 | return nullSafeHashCode((int[]) obj); 164 | } 165 | if (obj instanceof long[]) { 166 | return nullSafeHashCode((long[]) obj); 167 | } 168 | if (obj instanceof short[]) { 169 | return nullSafeHashCode((short[]) obj); 170 | } 171 | } 172 | return obj.hashCode(); 173 | } 174 | 175 | /** 176 | * Return a hash code based on the contents of the specified array. If 177 | * array is null, this method returns 0. 178 | * 179 | * @param array 180 | * the array for which to generate a hash code. 181 | * @return the array's hash code 182 | */ 183 | public static int nullSafeHashCode(Object... array) { 184 | if (array == null) { 185 | return 0; 186 | } 187 | int hash = INITIAL_HASH; 188 | int arraySize = array.length; 189 | for (int i = 0; i < arraySize; i++) { 190 | hash = MULTIPLIER * hash + nullSafeHashCode(array[i]); 191 | } 192 | return hash; 193 | } 194 | 195 | /** 196 | * Return a hash code based on the contents of the specified array. If 197 | * array is null, this method returns 0. 198 | * 199 | * @param array 200 | * the boolean array to hash 201 | * @return the generated hash code 202 | */ 203 | public static int nullSafeHashCode(boolean[] array) { 204 | if (array == null) { 205 | return 0; 206 | } 207 | int hash = INITIAL_HASH; 208 | int arraySize = array.length; 209 | for (int i = 0; i < arraySize; i++) { 210 | hash = MULTIPLIER * hash + hashCode(array[i]); 211 | } 212 | return hash; 213 | } 214 | 215 | /** 216 | * Return a hash code based on the contents of the specified array. If 217 | * array is null, this method returns 0. 218 | * 219 | * @param array 220 | * the byte array to hash 221 | * @return the generated hash code 222 | */ 223 | public static int nullSafeHashCode(byte[] array) { 224 | if (array == null) { 225 | return 0; 226 | } 227 | int hash = INITIAL_HASH; 228 | int arraySize = array.length; 229 | for (int i = 0; i < arraySize; i++) { 230 | hash = MULTIPLIER * hash + array[i]; 231 | } 232 | return hash; 233 | } 234 | 235 | /** 236 | * Return a hash code based on the contents of the specified array. If 237 | * array is null, this method returns 0. 238 | * 239 | * @param array 240 | * the char array to hash 241 | * @return the generated hash code 242 | */ 243 | public static int nullSafeHashCode(char[] array) { 244 | if (array == null) { 245 | return 0; 246 | } 247 | int hash = INITIAL_HASH; 248 | int arraySize = array.length; 249 | for (int i = 0; i < arraySize; i++) { 250 | hash = MULTIPLIER * hash + array[i]; 251 | } 252 | return hash; 253 | } 254 | 255 | /** 256 | * Return a hash code based on the contents of the specified array. If 257 | * array is null, this method returns 0. 258 | * 259 | * @param array 260 | * the double array to hash 261 | * @return the generated hash code 262 | */ 263 | public static int nullSafeHashCode(double[] array) { 264 | if (array == null) { 265 | return 0; 266 | } 267 | int hash = INITIAL_HASH; 268 | int arraySize = array.length; 269 | for (int i = 0; i < arraySize; i++) { 270 | hash = MULTIPLIER * hash + hashCode(array[i]); 271 | } 272 | return hash; 273 | } 274 | 275 | /** 276 | * Return a hash code based on the contents of the specified array. If 277 | * array is null, this method returns 0. 278 | * 279 | * @param array 280 | * the float array to hash 281 | * @return the generated hash code 282 | */ 283 | public static int nullSafeHashCode(float[] array) { 284 | if (array == null) { 285 | return 0; 286 | } 287 | int hash = INITIAL_HASH; 288 | int arraySize = array.length; 289 | for (int i = 0; i < arraySize; i++) { 290 | hash = MULTIPLIER * hash + hashCode(array[i]); 291 | } 292 | return hash; 293 | } 294 | 295 | /** 296 | * Return a hash code based on the contents of the specified array. If 297 | * array is null, this method returns 0. 298 | * 299 | * @param array 300 | * the int array to hash 301 | * @return the generated hash code 302 | */ 303 | public static int nullSafeHashCode(int[] array) { 304 | if (array == null) { 305 | return 0; 306 | } 307 | int hash = INITIAL_HASH; 308 | int arraySize = array.length; 309 | for (int i = 0; i < arraySize; i++) { 310 | hash = MULTIPLIER * hash + array[i]; 311 | } 312 | return hash; 313 | } 314 | 315 | /** 316 | * Return a hash code based on the contents of the specified array. If 317 | * array is null, this method returns 0. 318 | * 319 | * @param array 320 | * the long array to hash 321 | * @return the generated hash code 322 | */ 323 | public static int nullSafeHashCode(long[] array) { 324 | if (array == null) { 325 | return 0; 326 | } 327 | int hash = INITIAL_HASH; 328 | int arraySize = array.length; 329 | for (int i = 0; i < arraySize; i++) { 330 | hash = MULTIPLIER * hash + hashCode(array[i]); 331 | } 332 | return hash; 333 | } 334 | 335 | /** 336 | * Return a hash code based on the contents of the specified array. If 337 | * array is null, this method returns 0. 338 | * 339 | * @param array 340 | * the short array to hash 341 | * @return the generated hash code 342 | */ 343 | public static int nullSafeHashCode(short[] array) { 344 | if (array == null) { 345 | return 0; 346 | } 347 | int hash = INITIAL_HASH; 348 | int arraySize = array.length; 349 | for (int i = 0; i < arraySize; i++) { 350 | hash = MULTIPLIER * hash + array[i]; 351 | } 352 | return hash; 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/lang/OrderPreservingProperties.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.lang; 2 | 3 | import java.io.InputStream; 4 | import java.util.Collection; 5 | import java.util.LinkedHashMap; 6 | import java.util.Map; 7 | import java.util.NoSuchElementException; 8 | import java.util.Scanner; 9 | import java.util.Set; 10 | 11 | /** 12 | * Replacement for the java.util.Properties class that retains the order in 13 | * which the properties are defined. 14 | */ 15 | public class OrderPreservingProperties implements Map { 16 | 17 | public static final String DEFAULT_CHARSET_NAME = "UTF-8"; 18 | 19 | public static final String COMMENT_POUND = "#"; 20 | public static final String COMMENT_SEMICOLON = ";"; 21 | 22 | protected static final char ESCAPE_TOKEN = '\\'; 23 | 24 | private final Map props; 25 | 26 | public OrderPreservingProperties() { 27 | this.props = new LinkedHashMap(); 28 | } 29 | 30 | /** 31 | * Loads the .properties backed by the given InputStream into this instance. 32 | * This implementation will close the input stream after it has finished 33 | * loading. It is expected that the stream's contents are UTF-8 encoded. 34 | * 35 | * @param is 36 | * the {@code InputStream} from which to read the INI-formatted 37 | * text 38 | */ 39 | public void load(InputStream is) { 40 | // convert InputStream into a String in one shot: 41 | String string; 42 | try { 43 | string = new Scanner(is, DEFAULT_CHARSET_NAME).useDelimiter("\\A").next(); 44 | } catch (NoSuchElementException nsee) { 45 | string = ""; 46 | } 47 | 48 | Map props = toMapProps(string); 49 | putAll(props); 50 | } 51 | 52 | // Protected to access in a test case - NOT considered part of Shiro's 53 | // public API 54 | 55 | protected static boolean isContinued(String line) { 56 | if (!StringUtils.hasText(line)) { 57 | return false; 58 | } 59 | int length = line.length(); 60 | // find the number of backslashes at the end of the line. If an even 61 | // number, the 62 | // backslashes are considered escaped. If an odd number, the line is 63 | // considered continued on the next line 64 | int backslashCount = 0; 65 | for (int i = length - 1; i > 0; i--) { 66 | if (line.charAt(i) == ESCAPE_TOKEN) { 67 | backslashCount++; 68 | } else { 69 | break; 70 | } 71 | } 72 | return backslashCount % 2 != 0; 73 | } 74 | 75 | private static boolean isKeyValueSeparatorChar(char c) { 76 | return Character.isWhitespace(c) || c == ':' || c == '='; 77 | } 78 | 79 | private static boolean isCharEscaped(CharSequence s, int index) { 80 | return index > 0 && s.charAt(index - 1) == ESCAPE_TOKEN; 81 | } 82 | 83 | // Protected to access in a test case - NOT considered part of Shiro's 84 | // public API 85 | protected static String[] splitKeyValue(String keyValueLine) { 86 | String line = StringUtils.clean(keyValueLine); 87 | if (line == null) { 88 | return null; 89 | } 90 | StringBuilder keyBuffer = new StringBuilder(); 91 | StringBuilder valueBuffer = new StringBuilder(); 92 | 93 | boolean buildingKey = true; // we'll build the value next: 94 | 95 | for (int i = 0; i < line.length(); i++) { 96 | char c = line.charAt(i); 97 | 98 | if (buildingKey) { 99 | if (isKeyValueSeparatorChar(c) && !isCharEscaped(line, i)) { 100 | buildingKey = false;// now start building the value 101 | } else { 102 | keyBuffer.append(c); 103 | } 104 | } else { 105 | if (valueBuffer.length() == 0 && isKeyValueSeparatorChar(c) && !isCharEscaped(line, i)) { 106 | // swallow the separator chars before we start building the 107 | // value 108 | } else { 109 | valueBuffer.append(c); 110 | } 111 | } 112 | } 113 | 114 | String key = StringUtils.clean(keyBuffer.toString()); 115 | String value = StringUtils.clean(valueBuffer.toString()); 116 | 117 | if (key == null || value == null) { 118 | String msg = "Line argument must contain a key and a value. Only one string token was found."; 119 | throw new IllegalArgumentException(msg); 120 | } 121 | 122 | // log.trace("Discovered key/value pair: {}={}", key, value); 123 | 124 | return new String[] { key, value }; 125 | } 126 | 127 | private static Map toMapProps(String content) { 128 | Map props = new LinkedHashMap(); 129 | String line; 130 | StringBuilder lineBuffer = new StringBuilder(); 131 | Scanner scanner = new Scanner(content); 132 | while (scanner.hasNextLine()) { 133 | 134 | line = StringUtils.clean(scanner.nextLine()); 135 | 136 | if (line == null || line.startsWith(COMMENT_POUND) || line.startsWith(COMMENT_SEMICOLON)) { 137 | // skip empty lines and comments: 138 | continue; 139 | } 140 | 141 | if (isContinued(line)) { 142 | // strip off the last continuation backslash: 143 | line = line.substring(0, line.length() - 1); 144 | lineBuffer.append(line); 145 | continue; 146 | } else { 147 | lineBuffer.append(line); 148 | } 149 | line = lineBuffer.toString(); 150 | lineBuffer = new StringBuilder(); 151 | String[] kvPair = splitKeyValue(line); 152 | props.put(kvPair[0], kvPair[1]); 153 | } 154 | 155 | return props; 156 | } 157 | 158 | public void clear() { 159 | this.props.clear(); 160 | } 161 | 162 | public boolean containsKey(Object key) { 163 | return this.props.containsKey(key); 164 | } 165 | 166 | public boolean containsValue(Object value) { 167 | return this.props.containsValue(value); 168 | } 169 | 170 | public Set> entrySet() { 171 | return this.props.entrySet(); 172 | } 173 | 174 | public String get(Object key) { 175 | return this.props.get(key); 176 | } 177 | 178 | public boolean isEmpty() { 179 | return this.props.isEmpty(); 180 | } 181 | 182 | public Set keySet() { 183 | return this.props.keySet(); 184 | } 185 | 186 | public String put(String key, String value) { 187 | return this.props.put(key, value); 188 | } 189 | 190 | public void putAll(Map m) { 191 | this.props.putAll(m); 192 | } 193 | 194 | public String remove(Object key) { 195 | return this.props.remove(key); 196 | } 197 | 198 | public int size() { 199 | return this.props.size(); 200 | } 201 | 202 | public Collection values() { 203 | return this.props.values(); 204 | } 205 | 206 | @Override 207 | public boolean equals(Object obj) { 208 | if (obj instanceof OrderPreservingProperties) { 209 | OrderPreservingProperties other = (OrderPreservingProperties) obj; 210 | return this.props.equals(other.props); 211 | } 212 | return false; 213 | } 214 | 215 | @Override 216 | public int hashCode() { 217 | return ObjectUtils.nullSafeHashCode(this.props); 218 | } 219 | 220 | } 221 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/lang/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.lang; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | /** 8 | * Simple utility class for working with Strings. Partially copied from the 9 | * Spring framework and Apache Commons. 10 | * 11 | * @author Rod Johnson 12 | * @author Juergen Hoeller 13 | * @author Keith Donald 14 | * @author Rob Harrop 15 | * @author Rick Evans 16 | * @author Arjen Poutsma 17 | */ 18 | public class StringUtils { 19 | 20 | public static final String EMPTY_STRING = ""; 21 | 22 | /** 23 | * Take a String which is a delimited list and convert it to a String array. 24 | *

25 | * A single delimiter can consists of more than one character: It will still 26 | * be considered as single delimiter string, rather than as bunch of 27 | * potential delimiter characters - in contrast to 28 | * tokenizeToStringArray. 29 | * 30 | * @param str 31 | * the input String 32 | * @param delimiter 33 | * the delimiter between elements (this is a single delimiter, 34 | * rather than a bunch individual delimiter characters) 35 | * @return an array of the tokens in the list 36 | */ 37 | public static String[] delimitedListToStringArray(String str, String delimiter) { 38 | return delimitedListToStringArray(str, delimiter, null); 39 | } 40 | 41 | /** 42 | * Take a String which is a delimited list and convert it to a String array. 43 | *

44 | * A single delimiter can consists of more than one character: It will still 45 | * be considered as single delimiter string, rather than as bunch of 46 | * potential delimiter characters - in contrast to 47 | * tokenizeToStringArray. 48 | * 49 | * @param str 50 | * the input String 51 | * @param delimiter 52 | * the delimiter between elements (this is a single delimiter, 53 | * rather than a bunch individual delimiter characters) 54 | * @param charsToDelete 55 | * a set of characters to delete. Useful for deleting unwanted 56 | * line breaks: e.g. "\r\n\f" will delete all new lines and line 57 | * feeds in a String. 58 | * @return an array of the tokens in the list 59 | */ 60 | public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) { 61 | if (str == null) { 62 | return new String[0]; 63 | } 64 | if (delimiter == null) { 65 | return new String[] { str }; 66 | } 67 | List result = new ArrayList(); 68 | if ("".equals(delimiter)) { 69 | for (int i = 0; i < str.length(); i++) { 70 | result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); 71 | } 72 | } else { 73 | int pos = 0; 74 | int delPos; 75 | while ((delPos = str.indexOf(delimiter, pos)) != -1) { 76 | result.add(deleteAny(str.substring(pos, delPos), charsToDelete)); 77 | pos = delPos + delimiter.length(); 78 | } 79 | if (str.length() > 0 && pos <= str.length()) { 80 | // Add rest of String, but not in case of empty input. 81 | result.add(deleteAny(str.substring(pos), charsToDelete)); 82 | } 83 | } 84 | return toStringArray(result); 85 | } 86 | 87 | /** 88 | * Delete any character in a given String. 89 | * 90 | * @param inString 91 | * the original String 92 | * @param charsToDelete 93 | * a set of characters to delete. E.g. "az\n" will delete 'a's, 94 | * 'z's and new lines. 95 | * @return the resulting String 96 | */ 97 | public static String deleteAny(String inString, String charsToDelete) { 98 | if (!hasLength(inString) || !hasLength(charsToDelete)) { 99 | return inString; 100 | } 101 | StringBuilder sb = new StringBuilder(); 102 | for (int i = 0; i < inString.length(); i++) { 103 | char c = inString.charAt(i); 104 | if (charsToDelete.indexOf(c) == -1) { 105 | sb.append(c); 106 | } 107 | } 108 | return sb.toString(); 109 | } 110 | 111 | /** 112 | * Check that the given CharSequence is neither null nor of 113 | * length 0. Note: Will return true for a CharSequence that 114 | * purely consists of whitespace. 115 | *

116 | * 117 | *

118 | 	 * StringUtils.hasLength(null) = false
119 | 	 * StringUtils.hasLength("") = false
120 | 	 * StringUtils.hasLength(" ") = true
121 | 	 * StringUtils.hasLength("Hello") = true
122 | 	 * 
123 | * 124 | * @param str 125 | * the CharSequence to check (may be null) 126 | * @return true if the CharSequence is not null and has length 127 | * @see #hasText(String) 128 | */ 129 | public static boolean hasLength(CharSequence str) { 130 | return (str != null && str.length() > 0); 131 | } 132 | 133 | /** 134 | * Check that the given String is neither null nor of length 0. 135 | * Note: Will return true for a String that purely consists of 136 | * whitespace. 137 | * 138 | * @param str 139 | * the String to check (may be null) 140 | * @return true if the String is not null and has length 141 | * @see #hasLength(CharSequence) 142 | */ 143 | public static boolean hasLength(String str) { 144 | return hasLength((CharSequence) str); 145 | } 146 | 147 | /** 148 | * Copy the given Collection into a String array. The Collection must 149 | * contain String elements only. 150 | * 151 | * @param collection 152 | * the Collection to copy 153 | * @return the String array (null if the passed-in Collection 154 | * was null) 155 | */ 156 | public static String[] toStringArray(Collection collection) { 157 | if (collection == null) { 158 | return null; 159 | } 160 | return collection.toArray(new String[collection.size()]); 161 | } 162 | 163 | /** 164 | * Trim leading and trailing whitespace from the given String. 165 | * 166 | * @param str 167 | * the String to check 168 | * @return the trimmed String 169 | * @see java.lang.Character#isWhitespace 170 | */ 171 | public static String trimWhitespace(String str) { 172 | if (!hasLength(str)) { 173 | return str; 174 | } 175 | StringBuilder sb = new StringBuilder(str); 176 | while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { 177 | sb.deleteCharAt(0); 178 | } 179 | while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { 180 | sb.deleteCharAt(sb.length() - 1); 181 | } 182 | return sb.toString(); 183 | } 184 | 185 | /** 186 | * Split a String at the first occurrence of the delimiter. Does not include 187 | * the delimiter in the result. 188 | * 189 | * @param toSplit 190 | * the string to split 191 | * @param delimiter 192 | * to split the string up with 193 | * @return a two element array with index 0 being before the delimiter, and 194 | * index 1 being after the delimiter (neither element includes the 195 | * delimiter); or null if the delimiter wasn't found in 196 | * the given input String 197 | */ 198 | public static String[] split(String toSplit, String delimiter) { 199 | if (!hasLength(toSplit) || !hasLength(delimiter)) { 200 | return null; 201 | } 202 | int offset = toSplit.indexOf(delimiter); 203 | if (offset < 0) { 204 | return null; 205 | } 206 | String beforeDelimiter = toSplit.substring(0, offset); 207 | String afterDelimiter = toSplit.substring(offset + delimiter.length()); 208 | return new String[] { beforeDelimiter, afterDelimiter }; 209 | } 210 | 211 | /** 212 | * Check whether the given CharSequence has actual text. More specifically, 213 | * returns true if the string not null, its length 214 | * is greater than 0, and it contains at least one non-whitespace character. 215 | *

216 | * 217 | *

218 | 	 * StringUtils.hasText(null) = false
219 | 	 * StringUtils.hasText("") = false
220 | 	 * StringUtils.hasText(" ") = false
221 | 	 * StringUtils.hasText("12345") = true
222 | 	 * StringUtils.hasText(" 12345 ") = true
223 | 	 * 
224 | * 225 | * @param str 226 | * the CharSequence to check (may be null) 227 | * @return true if the CharSequence is not null, 228 | * its length is greater than 0, and it does not contain whitespace 229 | * only 230 | * @see java.lang.Character#isWhitespace 231 | */ 232 | public static boolean hasText(CharSequence str) { 233 | if (!hasLength(str)) { 234 | return false; 235 | } 236 | int strLen = str.length(); 237 | for (int i = 0; i < strLen; i++) { 238 | if (!Character.isWhitespace(str.charAt(i))) { 239 | return true; 240 | } 241 | } 242 | return false; 243 | } 244 | 245 | /** 246 | * Check whether the given String has actual text. More specifically, 247 | * returns true if the string not null, its length 248 | * is greater than 0, and it contains at least one non-whitespace character. 249 | * 250 | * @param str 251 | * the String to check (may be null) 252 | * @return true if the String is not null, its 253 | * length is greater than 0, and it does not contain whitespace only 254 | * @see #hasText(CharSequence) 255 | */ 256 | public static boolean hasText(String str) { 257 | return hasText((CharSequence) str); 258 | } 259 | 260 | /** 261 | * Returns a 'cleaned' representation of the specified argument. 'Cleaned' 262 | * is defined as the following: 263 | *

264 | *

    265 | *
  1. If the specified String is null, return 266 | * null
  2. 267 | *
  3. If not null, {@link String#trim() trim()} it.
  4. 268 | *
  5. If the trimmed string is equal to the empty String (i.e. 269 | * ""), return null
  6. 270 | *
  7. If the trimmed string is not the empty string, return the trimmed 271 | * version
  8. . 272 | *
273 | *

274 | * Therefore this method always ensures that any given string has trimmed 275 | * text, and if it doesn't, null is returned. 276 | * 277 | * @param in 278 | * the input String to clean. 279 | * @return a populated-but-trimmed String or null otherwise 280 | */ 281 | public static String clean(String in) { 282 | String out = in; 283 | 284 | if (in != null) { 285 | out = in.trim(); 286 | if (out.equals(EMPTY_STRING)) { 287 | out = null; 288 | } 289 | } 290 | 291 | return out; 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/providers/DefaultExceptionMapper.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.providers; 2 | 3 | import java.io.InputStream; 4 | import java.util.Collections; 5 | import java.util.LinkedHashMap; 6 | import java.util.Map; 7 | 8 | import javax.ws.rs.core.MediaType; 9 | import javax.ws.rs.core.Response; 10 | import javax.ws.rs.ext.ExceptionMapper; 11 | import javax.ws.rs.ext.Provider; 12 | 13 | import com.texelz.atgrestful.error.RestError; 14 | import com.texelz.atgrestful.lang.ClassUtils; 15 | import com.texelz.atgrestful.lang.OrderPreservingProperties; 16 | import com.texelz.atgrestful.lang.StringUtils; 17 | 18 | /** 19 | * 20 | * @author Onhate 21 | * 22 | */ 23 | @Provider 24 | public class DefaultExceptionMapper implements ExceptionMapper { 25 | 26 | public static final String DEFAULT_EXCEPTION_MESSAGE_VALUE = "_exmsg"; 27 | public static final String EXCEPTION_CONFIG_DELIMITER = "|"; 28 | 29 | private Map exceptionMappings = Collections.emptyMap(); 30 | 31 | public DefaultExceptionMapper() { 32 | // should be cleaner, but this is fine for a demo: 33 | InputStream is = ClassUtils.getResourceAsStream("rest-errors.properties"); 34 | OrderPreservingProperties props = new OrderPreservingProperties(); 35 | props.load(is); 36 | this.exceptionMappings = toRestErrors(props); 37 | } 38 | 39 | @Override 40 | public Response toResponse(Throwable t) { 41 | RestError error = getRestError(t); 42 | return Response.status(Response.Status.fromStatusCode(error.getStatus().value())) 43 | .type(MediaType.APPLICATION_JSON_TYPE).entity(error.toMap()).build(); 44 | } 45 | 46 | private RestError getRestError(Throwable t) { 47 | 48 | RestError template = getRestErrorTemplate(t); 49 | if (template == null) { 50 | return null; 51 | } 52 | 53 | RestError.Builder builder = new RestError.Builder(); 54 | builder.setStatus(template.getStatus()); 55 | builder.setCode(template.getCode()); 56 | builder.setThrowable(t); 57 | 58 | String msg = getMessage(template.getMessage(), t); 59 | if (msg != null) { 60 | builder.setMessage(msg); 61 | } 62 | msg = getMessage(template.getDeveloperMessage(), t); 63 | if (msg != null) { 64 | builder.setDeveloperMessage(msg); 65 | } 66 | 67 | return builder.build(); 68 | } 69 | 70 | /** 71 | * Returns the response status message to return to the client, or 72 | * {@code null} if no status message should be returned. 73 | * 74 | * @return the response status message to return to the client, or 75 | * {@code null} if no status message should be returned. 76 | */ 77 | protected String getMessage(String msg, Throwable t) { 78 | 79 | if (msg != null) { 80 | if (msg.equalsIgnoreCase("null") || msg.equalsIgnoreCase("off")) { 81 | return null; 82 | } 83 | if (msg.equalsIgnoreCase(DEFAULT_EXCEPTION_MESSAGE_VALUE)) { 84 | msg = t.getMessage(); 85 | } 86 | /* 87 | * if (messageSource != null) { Locale locale = null; if 88 | * (localeResolver != null) { locale = 89 | * localeResolver.resolveLocale(webRequest.getRequest()); } msg = 90 | * messageSource.getMessage(msg, null, msg, locale); } 91 | */ 92 | } 93 | 94 | return msg; 95 | } 96 | 97 | private RestError getRestErrorTemplate(Throwable t) { 98 | Map mappings = this.exceptionMappings; 99 | if (mappings == null || mappings.isEmpty()) { 100 | return null; 101 | } 102 | RestError template = null; 103 | int deepest = Integer.MAX_VALUE; 104 | for (Map.Entry entry : mappings.entrySet()) { 105 | String key = entry.getKey(); 106 | int depth = getDepth(key, t); 107 | if (depth >= 0 && depth < deepest) { 108 | deepest = depth; 109 | template = entry.getValue(); 110 | } 111 | } 112 | return template; 113 | } 114 | 115 | /** 116 | * Return the depth to the superclass matching. 117 | *

118 | * 0 means ex matches exactly. Returns -1 if there's no match. Otherwise, 119 | * returns depth. Lowest depth wins. 120 | */ 121 | protected int getDepth(String exceptionMapping, Throwable t) { 122 | return getDepth(exceptionMapping, t.getClass(), 0); 123 | } 124 | 125 | @SuppressWarnings("rawtypes") 126 | private int getDepth(String exceptionMapping, Class exceptionClass, int depth) { 127 | if (exceptionClass.getName().contains(exceptionMapping)) { 128 | // Found it! 129 | return depth; 130 | } 131 | // If we've gone as far as we can go and haven't found it... 132 | if (exceptionClass.equals(Throwable.class)) { 133 | return -1; 134 | } 135 | return getDepth(exceptionMapping, exceptionClass.getSuperclass(), depth + 1); 136 | } 137 | 138 | private static int getRequiredInt(String key, String value) { 139 | try { 140 | int anInt = Integer.valueOf(value); 141 | return Math.max(-1, anInt); 142 | } catch (NumberFormatException e) { 143 | String msg = "Configuration element '" + key + "' requires an integer value. The value " + "specified: " 144 | + value; 145 | throw new IllegalArgumentException(msg, e); 146 | } 147 | } 148 | 149 | private static int getInt(String key, String value) { 150 | try { 151 | return getRequiredInt(key, value); 152 | } catch (IllegalArgumentException iae) { 153 | return 0; 154 | } 155 | } 156 | 157 | private static Map toRestErrors(Map smap) { 158 | if (smap == null || smap.isEmpty()) { 159 | return Collections.emptyMap(); 160 | } 161 | 162 | Map map = new LinkedHashMap(smap.size()); 163 | 164 | for (Map.Entry entry : smap.entrySet()) { 165 | String key = entry.getKey(); 166 | String value = entry.getValue(); 167 | RestError template = toRestError(value); 168 | map.put(key, template); 169 | } 170 | 171 | return map; 172 | } 173 | 174 | private static RestError toRestError(String exceptionConfig) { 175 | String[] values = StringUtils.delimitedListToStringArray(exceptionConfig, EXCEPTION_CONFIG_DELIMITER); 176 | if (values == null || values.length == 0) { 177 | throw new IllegalStateException( 178 | "Invalid config mapping. Exception names must map to a string configuration."); 179 | } 180 | if (values.length > 5) { 181 | throw new IllegalStateException("Invalid config mapping. Mapped values must not contain more than 2 " 182 | + "values (code=y, msg=z, devMsg=x)"); 183 | } 184 | 185 | RestError.Builder builder = new RestError.Builder(); 186 | 187 | boolean statusSet = false; 188 | boolean codeSet = false; 189 | boolean msgSet = false; 190 | boolean devMsgSet = false; 191 | 192 | for (String value : values) { 193 | 194 | String trimmedVal = StringUtils.trimWhitespace(value); 195 | 196 | // check to see if the value is an explicitly named key/value pair: 197 | String[] pair = StringUtils.split(trimmedVal, "="); 198 | if (pair != null) { 199 | // explicit attribute set: 200 | String pairKey = StringUtils.trimWhitespace(pair[0]); 201 | if (!StringUtils.hasText(pairKey)) { 202 | pairKey = null; 203 | } 204 | String pairValue = StringUtils.trimWhitespace(pair[1]); 205 | if (!StringUtils.hasText(pairValue)) { 206 | pairValue = null; 207 | } 208 | if ("status".equalsIgnoreCase(pairKey)) { 209 | int statusCode = getRequiredInt(pairKey, pairValue); 210 | builder.setStatus(statusCode); 211 | statusSet = true; 212 | } else if ("code".equalsIgnoreCase(pairKey)) { 213 | int code = getRequiredInt(pairKey, pairValue); 214 | builder.setCode(code); 215 | codeSet = true; 216 | } else if ("msg".equalsIgnoreCase(pairKey)) { 217 | builder.setMessage(pairValue); 218 | msgSet = true; 219 | } else if ("devMsg".equalsIgnoreCase(pairKey)) { 220 | builder.setDeveloperMessage(pairValue); 221 | devMsgSet = true; 222 | } 223 | } else { 224 | // not a key/value pair - use heuristics to determine what value 225 | // is being set: 226 | int val; 227 | if (!statusSet) { 228 | val = getInt("status", trimmedVal); 229 | if (val > 0) { 230 | builder.setStatus(val); 231 | statusSet = true; 232 | continue; 233 | } 234 | } 235 | if (!codeSet) { 236 | val = getInt("code", trimmedVal); 237 | if (val > 0) { 238 | builder.setCode(val); 239 | codeSet = true; 240 | continue; 241 | } 242 | } 243 | if (!msgSet) { 244 | builder.setMessage(trimmedVal); 245 | msgSet = true; 246 | continue; 247 | } 248 | if (!devMsgSet) { 249 | builder.setDeveloperMessage(trimmedVal); 250 | devMsgSet = true; 251 | continue; 252 | } 253 | } 254 | } 255 | 256 | return builder.build(); 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/com/texelz/atgrestful/providers/NucleusProducer.java: -------------------------------------------------------------------------------- 1 | package com.texelz.atgrestful.providers; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import javax.ws.rs.ext.Provider; 6 | 7 | import atg.servlet.DynamoHttpServletRequest; 8 | import atg.servlet.ServletUtil; 9 | 10 | import com.sun.jersey.core.spi.component.ComponentContext; 11 | import com.sun.jersey.core.spi.component.ComponentScope; 12 | import com.sun.jersey.spi.inject.Injectable; 13 | import com.sun.jersey.spi.inject.InjectableProvider; 14 | import com.texelz.atgrestful.Nucleus; 15 | 16 | /** 17 | * The {@link Nucleus} annotation provider. So, when you annotated your 18 | * property, this class will works on provide the component object 19 | * 20 | * @author Onhate 21 | * 22 | */ 23 | @Provider 24 | public class NucleusProducer implements InjectableProvider { 25 | 26 | /** 27 | * The class that will lookup the Nucleus component 28 | * 29 | * @author Onhate 30 | * 31 | */ 32 | class NucleusInjectable implements Injectable { 33 | private Nucleus nucleus; 34 | 35 | public NucleusInjectable(Nucleus nucleus) { 36 | this.nucleus = nucleus; 37 | } 38 | 39 | /** 40 | * Returns the component value ;) 41 | */ 42 | @Override 43 | public Object getValue() { 44 | DynamoHttpServletRequest request = ServletUtil.getCurrentRequest(); 45 | String componentName = nucleus.value(); 46 | Object result = request.resolveName(componentName); 47 | return result; 48 | } 49 | } 50 | 51 | @SuppressWarnings("rawtypes") 52 | @Override 53 | public Injectable getInjectable(ComponentContext componentContext, final Nucleus nucleus, Type type) { 54 | return new NucleusInjectable(nucleus); 55 | } 56 | 57 | @Override 58 | public ComponentScope getScope() { 59 | return ComponentScope.PerRequest; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Texelz/RESTful/src/rest-errors.properties: -------------------------------------------------------------------------------- 1 | # 400 2 | IllegalArgumentException = 400 | _exmsg 3 | javax.validation.ValidationException = 400 | _exmsg 4 | atg.droplet.DropletException = 400 | _exmsg 5 | 6 | # 404 7 | UnknownResourceException = 404 | _exmsg 8 | com.sun.jersey.api.NotFoundException = 404 | The specified resource does not exist. | The specified resource does not exist. 9 | 10 | Throwable = 500 --------------------------------------------------------------------------------