/** * Test if type is map. Returns true if type implements, directly or through inheritance, {@link Map} interface. * * @param t type to test. * @return true if type is map. */ public static boolean isMap(Type t) { return Types.isKindOf(t, Map.class); }
/** * Test if type is a calendar date. * * @param t type to test. * @return true if type is a calendar date. */ public static boolean isDate(Type t) { return isKindOf(t, Date.class); }
/** * Test if type is a stream, either bytes or characters stream. * * @param type type to test. * @return true type is a stream. */ public static boolean isStream(Type type) { return Types.isKindOf(type, InputStream.class, Reader.class); } }
/** * Test if type is collection. Returns true if type implements, directly or through inheritance, {@link Collection} * interface. * * @param t type to test. * @return true if type is collection. */ public static boolean isCollection(Type t) { return Types.isKindOf(t, Collection.class); }
/** * Return field class or actual type argument if given field is a list. * * @param field Java reflective class field. * @return field type. */ private static Class<?> type(Field field) { if (Types.isKindOf(field.getType(), List.class)) { // for the purpose of this implementation only first parameterized // type matters, as result from list declaration List<E> return (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; } return field.getType(); } }
/** * Test if parameter is of requested type and throw exception if not. * * @param parameter invocation parameter, * @param typeToMatch type to match, * @param name the name of invocation parameter. * @throws IllegalArgumentException if parameter is not of requested type. */ public static void isKindOf(Type parameter, Type typeToMatch, String name) { if (!Types.isKindOf(parameter, typeToMatch)) { throw new IllegalArgumentException(Strings.format("%s is not %s.", name, typeToMatch)); } } }
/** * Process XML input stream accordingly requested type. Current implementation supports two type: XML {@link Document} and * XML input stream. * * @param inputStream XML input stream, * @param type expected Java type. * @return XML stream processing result. * @throws IOException if XML stream reading fails. * @throws IllegalArgumentException if requested Java type is not supported. */ @Override public Object read(InputStream inputStream, Type type) throws IOException { if (Types.isKindOf(type, Document.class)) { return documentBuilder.loadXML(inputStream); } else if (Types.isKindOf(type, InputStream.class)) { threadLocal.set(inputStream); return inputStream; } else { throw new IllegalArgumentException("Unsupported formal parameter type |%s| for XML content type.", type); } }
/** * Determine if a given type is a kind of one of the requested types to match. Traverses <code>typesToMatch</code> and * delegates {@link #isKindOf(Type, Type)} till first positive match and returns true. If no match found returns * false. If <code>type</code> is null returns false. If a type to match happened to be null is considered no match. * * @param t type to test, possible null, * @param typesToMatch variable number of types to match. * @return true if <code>type</code> is a kind of one of <code>typesToMatch</code>. * @throws IllegalArgumentException if <code>typesToMach</code> is null or empty. */ public static boolean isKindOf(Type t, Type... typesToMatch) throws IllegalArgumentException { Params.notNullOrEmpty(typesToMatch, "Types to match"); for(Type typeToMatch : typesToMatch) { if(isKindOf(t, typeToMatch)) { return true; } } return false; }
private static Format createFormatter(String className) { Class<? extends Format> formatterClass = Classes.forName(className); if (Types.isKindOf(formatterClass, Format.class)) { return Classes.newInstance(formatterClass); } return null; } }
/** * Create an object instance of the requested type. If type is a {@link List} uses * {@link Classes#getListDefaultImplementation(Type)}. * * @param type object type. * @return newly created instance. */ public Object newInstance(Class<?> type) { if (Types.isKindOf(type, List.class)) { type = Classes.getListDefaultImplementation(type); } return Classes.newInstance(type); }
/** * Create form object node wrapping given plain Java object. * * @param object plain Java object that created form object node should wrap, * @param type component type used only if wrapped object is a list. * @return node for requested class. */ public Node createNode(Object object, Class<?> type) { if (Types.isKindOf(object.getClass(), List.class)) { return new ListNode(object, type); } if (object.getClass().isArray()) { return new ArrayNode(object); } return new ObjectNode(object); } }
/** * Set value to wrapped object field identified by requested child name. Given string value is converted to wrapped * object type using {@link Converter}. * * @param childName wrapped object field name, * @param value string value loaded from form field, null and empty accepted. * @throws ConverterException if field value conversion fails. * @throws IllegalAccessException this exception is required by reflective field signature but never thrown. */ @Override public void setValue(String childName, Object value) throws ConverterException, IllegalAccessException { Field field = null; try { field = Classes.getFieldEx(object.getClass(), Strings.toMemberName(childName)); } catch (NoSuchFieldException e) { // best effort approach: form to object mapping is not so strictly - i.e. ignores missing fields log.debug("Missing field |%s| from object |%s|.", childName, object.getClass()); return; } if (value instanceof UploadedFile) { if (Types.isKindOf(field.getType(), File.class)) { field.set(object, ((UploadedFile) value).getFile()); } else { field.set(object, value); } } else { field.set(object, converter.asObject((String) value, field.getType())); } } }
/** * Beside initialization performed by {@link AppServlet#init(ServletConfig)} this method takes care to load resource methods * cache. A resource method is a remotely accessible method that returns a {@link Resource}. Map storage key is generated by * {@link #key(ManagedMethodSPI)} based on controller and resource method request paths and is paired with retrieval key - * {@link #key(String)}, generated from request path when method invocation occurs. * * @param config servlet configuration object. * @throws UnavailableException if tiny container is not properly initialized. */ @Override public void init(ServletConfig config) throws UnavailableException { super.init(config); for (ManagedMethodSPI method : container.getManagedMethods()) { if (Types.isKindOf(method.getReturnType(), Resource.class)) { resourceMethods.put(key(method), method); } } }
/** * Get managed method that is remotely accessible and has requested name. * * @param managedClass managed class where method is supposed to be declared, * @param methodName method name, * @param requestURI request URI for logging. * @return managed method, never null. * @throws NoSuchMethodException if managed class has not any method with requested name, managed method was found but is * not remotely accessible or it returns a {@link Resource}. */ private static ManagedMethodSPI getManagedMethod(ManagedClassSPI managedClass, String methodName, String requestURI) throws NoSuchMethodException { ManagedMethodSPI managedMethod = managedClass.getNetMethod(methodName); if (managedMethod == null) { log.error("HTTP-RMI request for not existing managed method |%s#%s|.", managedClass.getInterfaceClass().getName(), methodName); throw new NoSuchMethodException(requestURI); } if (!managedMethod.isRemotelyAccessible()) { log.error("HTTP-RMI request for local managed method |%s#%s|. See @Remote annotation.", managedClass.getInterfaceClass().getName(), methodName); throw new NoSuchMethodException(requestURI); } if (Types.isKindOf(managedMethod.getReturnType(), Resource.class)) { log.error("HTTP-RMI request for managed method |%s#%s| returning a resource.", managedClass.getInterfaceClass().getName(), methodName); throw new NoSuchMethodException(requestURI); } return managedMethod; }
if (Types.isKindOf(managedClass.getImplementationClass(), ManagedPreDestroy.class)) { sortedClasses.add(managedClass);
/** * Performed super-initialization by {@link AppServlet#init(ServletConfig)} and loads REST methods cache. A REST method is a * remotely accessible method that does not return a {@link Resource}. Map storage key is generated by * {@link #key(ManagedMethodSPI)} based on managed class and REST method request paths and is paired with retrieval key - * {@link #key(String)}, generated from request path info when method invocation occurs. * * @param config servlet configuration object. * @throws UnavailableException if tiny container is not properly initialized. */ @Override public void init(ServletConfig config) throws UnavailableException { super.init(config); for (ManagedMethodSPI managedMethod : container.getManagedMethods()) { if (!managedMethod.isRemotelyAccessible()) { continue; } if (!Types.isKindOf(managedMethod.getReturnType(), Resource.class)) { restMethods.put(key(managedMethod), managedMethod); } } }
if (Types.isKindOf(managedClass.getImplementationClass(), ManagedLifeCycle.class)) { sortedClasses.add(managedClass);
return (T) strings.toArray(new String[strings.size()]); if (Types.isKindOf(type, Collection.class)) { Type collectionType = type; Class<?> itemType = String.class;
throw new ConfigException("Managed class implementation |%s| cannot be abstract. See class descriptor |%s|.", implementationClass, descriptor); if (Types.isKindOf(implementationClass, ManagedLifeCycle.class) && !InstanceScope.APPLICATION.equals(instanceScope)) { throw new ConfigException("Bad scope |%s| used with managed life cycle. See class descriptor |%s|.", instanceScope, descriptor);