private boolean testCookie( Cookie ck, String name, String value, String path, String domain, int version) throws Exception { StringBuffer sb = new StringBuffer(); boolean pass = true; if (name == "" || name == null) { pass = false; sb.append("Cookie's name is empty"); } else if (!ck.getName().toLowerCase().equals(name)) { pass = false; sb.append("Failed name test. Expect " + name + " got " + ck.getName()); } if (value == "" || value == null) { pass = false; sb.append("Cookie's value is empty"); } else if (!ck.getValue().toLowerCase().equals(value)) { pass = false; sb.append("Failed value test. Expect " + value + " got " + ck.getValue()); } if (ck.getVersion() != version) { pass = false; sb.append("Failed version test. Expect " + version + " got " + ck.getVersion()); } if (path == "" || path == null) { if (ck.getPath() != "" && ck.getPath() != null) { pass = false; sb.append("Failed path test. Expect null String, got " + ck.getPath()); } } else if (ck.getPath() == null || ck.getPath() == "") { pass = false; sb.append("Failed path test. Got null, expecting " + path); } else if (!ck.getPath().toLowerCase().equals(path)) { pass = false; sb.append("Failed path test. Expect " + path + " got " + ck.getPath()); } if (domain == "" || domain == null) { if (ck.getDomain() != "" && ck.getDomain() != null) { pass = false; sb.append("Failed path test. Expect " + domain + " got " + ck.getDomain()); } } else if (!ck.getDomain().toLowerCase().equals(domain)) { pass = false; sb.append("Failed domain test. Expect " + domain + " got " + ck.getDomain()); } if (!pass) { throw new Exception("At least one assertion falied: " + sb.toString()); } return pass; }
@Override @SuppressWarnings("unchecked") public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // get the interface describing the resource Class<?> proxyIfc = proxy.getClass().getInterfaces()[0]; // response type Class<?> responseType = method.getReturnType(); // determine method name String httpMethod = getHttpMethodName(method); if (httpMethod == null) { for (Annotation ann : method.getAnnotations()) { httpMethod = getHttpMethodName(ann.annotationType()); if (httpMethod != null) { break; } } } // create a new UriBuilder appending the @Path attached to the method WebTarget newTarget = addPathFromAnnotation(method, target); if (httpMethod == null) { if (newTarget == target) { // no path annotation on the method -> fail throw new UnsupportedOperationException("Not a resource method."); } else if (!responseType.isInterface()) { // the method is a subresource locator, but returns class, // not interface - can't help here throw new UnsupportedOperationException("Return type not an interface"); } } // process method params (build maps of (Path|Form|Cookie|Matrix|Header..)Params // and extract entity type MultivaluedHashMap<String, Object> headers = new MultivaluedHashMap<String, Object>(this.headers); LinkedList<Cookie> cookies = new LinkedList<Cookie>(this.cookies); Form form = new Form(); form.asMap().putAll(this.form.asMap()); Annotation[][] paramAnns = method.getParameterAnnotations(); Object entity = null; Type entityType = null; for (int i = 0; i < paramAnns.length; i++) { Map<Class, Annotation> anns = new HashMap<Class, Annotation>(); for (Annotation ann : paramAnns[i]) { anns.put(ann.annotationType(), ann); } Annotation ann; Object value = args[i]; if (anns.isEmpty()) { entityType = method.getGenericParameterTypes()[i]; entity = value; } else { if (value == null && (ann = anns.get(DefaultValue.class)) != null) { value = ((DefaultValue) ann).value(); } if (value != null) { if ((ann = anns.get(PathParam.class)) != null) { newTarget = newTarget.resolveTemplate(((PathParam) ann).value(), value); } else if ((ann = anns.get((QueryParam.class))) != null) { if (value instanceof Collection) { newTarget = newTarget.queryParam(((QueryParam) ann).value(), convert((Collection) value)); } else { newTarget = newTarget.queryParam(((QueryParam) ann).value(), value); } } else if ((ann = anns.get((HeaderParam.class))) != null) { if (value instanceof Collection) { headers.addAll(((HeaderParam) ann).value(), convert((Collection) value)); } else { headers.addAll(((HeaderParam) ann).value(), value); } } else if ((ann = anns.get((CookieParam.class))) != null) { String name = ((CookieParam) ann).value(); Cookie c; if (value instanceof Collection) { for (Object v : ((Collection) value)) { if (!(v instanceof Cookie)) { c = new Cookie(name, v.toString()); } else { c = (Cookie) v; if (!name.equals(((Cookie) v).getName())) { // is this the right thing to do? or should I fail? or ignore the difference? c = new Cookie(name, c.getValue(), c.getPath(), c.getDomain(), c.getVersion()); } } cookies.add(c); } } else { if (!(value instanceof Cookie)) { cookies.add(new Cookie(name, value.toString())); } else { c = (Cookie) value; if (!name.equals(((Cookie) value).getName())) { // is this the right thing to do? or should I fail? or ignore the difference? cookies.add( new Cookie(name, c.getValue(), c.getPath(), c.getDomain(), c.getVersion())); } } } } else if ((ann = anns.get((MatrixParam.class))) != null) { if (value instanceof Collection) { newTarget = newTarget.matrixParam(((MatrixParam) ann).value(), convert((Collection) value)); } else { newTarget = newTarget.matrixParam(((MatrixParam) ann).value(), value); } } else if ((ann = anns.get((FormParam.class))) != null) { if (value instanceof Collection) { for (Object v : ((Collection) value)) { form.param(((FormParam) ann).value(), v.toString()); } } else { form.param(((FormParam) ann).value(), value.toString()); } } } } } if (httpMethod == null) { // the method is a subresource locator return WebResourceFactory.newResource(responseType, newTarget, true, headers, cookies, form); } // accepted media types Produces produces = method.getAnnotation(Produces.class); if (produces == null) { produces = proxyIfc.getAnnotation(Produces.class); } String[] accepts = produces == null ? null : produces.value(); // determine content type String contentType = null; if (entity != null) { Consumes consumes = method.getAnnotation(Consumes.class); if (consumes == null) { consumes = proxyIfc.getAnnotation(Consumes.class); } if (consumes != null && consumes.value().length > 0) { // TODO: should consider q/qs instead of picking the first one contentType = consumes.value()[0]; } } Invocation.Builder builder; if (accepts != null) { builder = newTarget.request(accepts); } else { builder = newTarget.request(); } // apply header params and cookies builder.headers(headers); for (Cookie c : cookies) { builder = builder.cookie(c); } Object result; if (entity == null && !form.asMap().isEmpty()) { entity = form; contentType = MediaType.APPLICATION_FORM_URLENCODED; } else { if (contentType == null) { contentType = MediaType.APPLICATION_OCTET_STREAM; } if (!form.asMap().isEmpty()) { if (entity instanceof Form) { ((Form) entity).asMap().putAll(form.asMap()); } else { // TODO: should at least log some warning here } } } GenericType responseGenericType = new GenericType(method.getGenericReturnType()); if (entity != null) { if (entityType instanceof ParameterizedType) { entity = new GenericEntity(entity, entityType); } result = builder.method(httpMethod, Entity.entity(entity, contentType), responseGenericType); } else { result = builder.method(httpMethod, responseGenericType); } return result; }