Example usage for java.lang.reflect Method getModifiers

List of usage examples for java.lang.reflect Method getModifiers

Introduction

In this page you can find the example usage for java.lang.reflect Method getModifiers.

Prototype

@Override
public int getModifiers() 

Source Link

Usage

From source file:hu.bme.mit.sette.common.model.snippet.SnippetContainer.java

/**
 * Validates methods of the class./*from   w w w  .j  a v a  2 s  .  c o m*/
 *
 * @param validator
 *            a validator
 * @return a map containing the snippet methods by their name
 */
private Map<String, Method> validateMethods(final AbstractValidator<?> validator) {
    // check: only "[public|private] static" or synthetic methods
    Map<String, Method> snippetMethods = new HashMap<String, Method>();

    for (Method method : javaClass.getDeclaredMethods()) {
        if (method.isSynthetic()) {
            // skip synthetic methods
            continue;
        }

        MethodValidator v = new MethodValidator(method);

        if (snippetMethods.get(method.getName()) != null) {
            v.addException("The method must have a unique name");
        }

        int methodModifiers = method.getModifiers();

        if (!Modifier.isPublic(methodModifiers) && !Modifier.isPrivate(methodModifiers)) {
            v.addException("The method must be public or private");
        }

        v.withModifiers(Modifier.STATIC);
        v.withoutModifiers(Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE | Modifier.SYNCHRONIZED);

        AnnotationMap methodAnns = SetteAnnotationUtils.getSetteAnnotations(method);

        if (Modifier.isPublic(methodModifiers)) {
            if (methodAnns.get(SetteNotSnippet.class) == null) {
                // should be snippet, validated by Snippet class and added
                // later
                snippetMethods.put(method.getName(), method);
            } else {
                // not snippet
                snippetMethods.put(method.getName(), null);

                if (methodAnns.size() != 1) {
                    v.addException("The method must not have " + "any other SETTE annotations "
                            + "if it is not a snippet.");
                }
            }
        } else {
            // method is private
            if (methodAnns.size() != 0) {
                v.addException("The method must not have " + "any SETTE annotations");
            }
        }

        validator.addChildIfInvalid(v);
    }

    return snippetMethods;
}

From source file:jp.go.nict.langrid.servicecontainer.handler.jsonrpc.servlet.JsonRpcServlet.java

/**
 * //from w  ww.  jav a2  s  .c  o m
 * 
 */
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServiceContext sc = new ServletConfigServiceContext(getServletConfig());
    HttpServletRequestParameterContext param = new HttpServletRequestParameterContext(req);
    if (param.getValue("sample") == null && param.getValue("method") != null && getMethodEnabled) {
        doProcess(req, resp);
        return;
    }
    ServiceLoader loader = new ServiceLoader(sc, defaultLoaders);
    String sample = param.getValue("sample");
    if (sample != null) {
        resp.setContentType("text/plain");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter os = resp.getWriter();
        String serviceName = getServiceName(req);
        String method = req.getParameter("method");
        os.println("request:");
        printSampleRequest(loader, serviceName, method, os);
        os.println("");
        os.println("");
        os.println("response:");
        printSampleResponse(loader, serviceName, method, os);
        os.flush();
        return;
    }
    String uri = req.getRequestURI();
    String cp = getServletContext().getContextPath();
    int idx = uri.indexOf(cp);
    if (idx == -1) {
        super.doGet(req, resp);
        return;
    }
    int sidx = uri.indexOf('/', idx + cp.length() + 1);
    if (sidx != -1) {
        resp.sendRedirect(uri.substring(idx, sidx));
        return;
    }

    resp.setContentType("text/html");
    resp.setCharacterEncoding("UTF-8");
    PrintWriter w = resp.getWriter();
    w.println("<html><head>");
    w.println(css);
    w.println(js);
    w.println("</head><body>");
    w.println("<h2>And now... Some JsonRpc Services</h2>");
    w.println("<ul>");
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    Set<String> names = new TreeSet<String>();
    try {
        for (String s : loader.listServiceNames()) {
            names.add(s);
        }
        int id = 0;
        for (String s : names) {
            w.print("<li><b>" + s);
            ServiceFactory f = loader.loadServiceFactory(cl, s);
            if (f == null) {
                w.println("<font color=\"red\">(Failed to load service factory(null))</font></b></li>");
                continue;
            }
            Object service = f.getService();
            if (service instanceof StreamingNotifier) {
                w.print("(Streaming ready!)");
            }
            String sdesc = RpcAnnotationUtil.getServiceDescriptions(Service.class, "en");
            if (sdesc != null && sdesc.length() > 0) {
                w.print(" - " + StringEscapeUtils.escapeHtml(sdesc));
            }
            w.print("</b><ul>");
            w.print("<li>interfaces<ul>");
            try {
                Set<Class<?>> visited = new HashSet<Class<?>>();
                for (Class<?> intf : f.getInterfaces()) {
                    if (visited.contains(intf))
                        continue;
                    visited.add(intf);
                    if (StreamingNotifier.class.isAssignableFrom(intf))
                        continue;
                    w.print("<li>" + prettyName(intf));
                    String desc = RpcAnnotationUtil.getServiceDescriptions(intf, "en");
                    if (desc != null && desc.length() > 0) {
                        w.print(" - " + StringEscapeUtils.escapeHtml(desc));
                    }
                    w.print("<ul>");
                    try {
                        Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() {
                            public int compare(Method o1, Method o2) {
                                int r = o1.getName().compareTo(o2.getName());
                                if (r != 0)
                                    return r;
                                return o1.getParameterTypes().length - o2.getParameterTypes().length;
                            }
                        });
                        methods.addAll(Arrays.asList(intf.getMethods()));
                        for (Method m : methods) {
                            if (m.isSynthetic())
                                continue;
                            if ((m.getModifiers() & Modifier.PUBLIC) == 0)
                                continue;
                            printMethod(s, m, getImplementedMethod(service, m), id++, w);
                        }
                    } finally {
                        w.println("</ul></li>");
                    }
                }
            } catch (SecurityException e) {
            } finally {
                w.println("</ul></li>");
            }
            w.print("<li>implementation<ul>");
            if (service != null) {
                w.println("<li>" + prettyName(service.getClass()) + "</li>");
                if (service instanceof AbstractCompositeService) {
                    boolean first = true;
                    for (Pair<Invocation, Class<?>> v : ((AbstractCompositeService) service).invocations()) {
                        if (first) {
                            w.println("<li>invocations<ul>");
                            first = false;
                        }
                        w.println(
                                "<li><b>" + v.getFirst().name() + (v.getFirst().required() ? "(required)" : "")
                                        + "</b>: " + prettyName(v.getSecond()) + "</li>");
                    }
                    if (!first) {
                        w.println("</ul></li>");
                    }
                }
            } else {
                w.println("<li><font color=\"red\"><b>failed to load implementation class.</b></font></li>");
            }
            w.println("</ul></li>");
            w.println("</ul></li>");
            w.println("<br/>");
        }
    } catch (IOException e) {
        w.println("<pre><font color=\"red\">");
        e.printStackTrace(w);
        w.println("</font></pre>");
    }
    w.println("</ul>");
    w.println("</body></html>");
}

From source file:eu.qualityontime.commons.MethodUtils.java

/**
 * <p>//  w  ww  .ja  v  a  2s .  c  o  m
 * Find an accessible method that matches the given name and has compatible
 * parameters. Compatible parameters mean that every method parameter is
 * assignable from the given parameters. In other words, it finds a method
 * with the given name that will take the parameters given.
 * </p>
 *
 * <p>
 * This method is slightly undeterministic since it loops through methods
 * names and return the first matching method.
 * </p>
 *
 * <p>
 * This method is used by
 * {@link #invokeMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}.
 *
 * <p>
 * This method can match primitive parameter by passing in wrapper classes.
 * For example, a <code>Boolean</code> will match a primitive
 * <code>boolean</code> parameter.
 *
 * @param clazz
 *            find method in this class
 * @param methodName
 *            find method with this name
 * @param parameterTypes
 *            find method with compatible parameters
 * @return The accessible method
 */
public static Method getMatchingAccessibleMethod(final Class<?> clazz, final String methodName,
        final Class<?>[] parameterTypes) {
    // trace logging
    final Log log = LogFactory.getLog(MethodUtils.class);
    if (log.isTraceEnabled()) {
        log.trace("Matching name=" + methodName + " on " + clazz);
    }
    final MethodDescriptor md = new MethodDescriptor(clazz, methodName, parameterTypes, false);

    // see if we can find the method directly
    // most of the time this works and it's much faster
    try {
        // Check the cache first
        Method method = getCachedMethod(md);
        if (method != null) {
            return method;
        }

        method = clazz.getMethod(methodName, parameterTypes);
        if (log.isTraceEnabled()) {
            log.trace("Found straight match: " + method);
            log.trace("isPublic:" + Modifier.isPublic(method.getModifiers()));
        }

        setMethodAccessible(method); // Default access superclass workaround

        cacheMethod(md, method);
        return method;

    } catch (final NoSuchMethodException e) {
        /* SWALLOW */ }

    // search through all methods
    final int paramSize = parameterTypes.length;
    Method bestMatch = null;
    final Method[] methods = clazz.getMethods();
    float bestMatchCost = Float.MAX_VALUE;
    float myCost = Float.MAX_VALUE;
    for (final Method method2 : methods) {
        if (method2.getName().equals(methodName)) {
            // log some trace information
            if (log.isTraceEnabled()) {
                log.trace("Found matching name:");
                log.trace(method2);
            }

            // compare parameters
            final Class<?>[] methodsParams = method2.getParameterTypes();
            final int methodParamSize = methodsParams.length;
            if (methodParamSize == paramSize) {
                boolean match = true;
                for (int n = 0; n < methodParamSize; n++) {
                    if (log.isTraceEnabled()) {
                        log.trace("Param=" + parameterTypes[n].getName());
                        log.trace("Method=" + methodsParams[n].getName());
                    }
                    if (!isAssignmentCompatible(methodsParams[n], parameterTypes[n])) {
                        if (log.isTraceEnabled()) {
                            log.trace(methodsParams[n] + " is not assignable from " + parameterTypes[n]);
                        }
                        match = false;
                        break;
                    }
                }

                if (match) {
                    // get accessible version of method
                    final Method method = getAccessibleMethod(clazz, method2);
                    if (method != null) {
                        if (log.isTraceEnabled()) {
                            log.trace(method + " accessible version of " + method2);
                        }
                        setMethodAccessible(method); // Default access
                        // superclass
                        // workaround
                        myCost = getTotalTransformationCost(parameterTypes, method.getParameterTypes());
                        if (myCost < bestMatchCost) {
                            bestMatch = method;
                            bestMatchCost = myCost;
                        }
                    }

                    log.trace("Couldn't find accessible method.");
                }
            }
        }
    }
    if (bestMatch != null) {
        cacheMethod(md, bestMatch);
    } else {
        // didn't find a match
        log.trace("No match found.");
    }

    return bestMatch;
}

From source file:com.zenesis.qx.remote.ProxyTypeImpl.java

/**
 * Constructor, used for defining interfaces which are to be proxied
 * @param className/*from   w  w w. j a v a  2  s .  c o m*/
 * @param methods
 */
public ProxyTypeImpl(ProxyType superType, Class clazz, Set<ProxyType> interfaces) {
    super();
    if (interfaces == null)
        interfaces = Collections.EMPTY_SET;
    this.superType = superType;
    this.interfaces = interfaces;
    this.clazz = clazz;

    MethodsCompiler methodsCompiler = new MethodsCompiler();

    // Get a complete list of methods from the interfaces that the new class has to 
    //   implement; we include methods marked as DoNotProxy so that we can check for 
    //   conflicting instructions
    if (!clazz.isInterface()) {
        // Get a full list of the interfaces which our class has to implement
        HashSet<ProxyType> allInterfaces = new HashSet<ProxyType>();
        getAllInterfaces(allInterfaces, interfaces);

        for (ProxyType ifcType : allInterfaces) {
            try {
                methodsCompiler.addMethods(Class.forName(ifcType.getClassName()), true);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException("Cannot find class " + ifcType.getClassName());
            }
        }
    }

    boolean defaultProxy = false;
    if (clazz.isInterface())
        defaultProxy = true;
    else {
        for (Class tmp = clazz; tmp != null; tmp = tmp.getSuperclass()) {
            if (factoryMethod == null) {
                for (Method method : tmp.getDeclaredMethods()) {
                    if (method.isAnnotationPresent(FactoryMethod.class)) {
                        if (!Modifier.isStatic(method.getModifiers()))
                            throw new IllegalStateException("Cannot use method " + method
                                    + " as FactoryMethod because it is not static");
                        factoryMethod = method;
                        method.setAccessible(true);
                        break;
                    }
                }
            }
            if (tmp.isAnnotationPresent(AlwaysProxy.class)) {
                defaultProxy = true;
                break;
            } else if (tmp.isAnnotationPresent(ExplicitProxyOnly.class)) {
                break;
            }
        }
    }

    // If the class does not have any proxied interfaces or the class is marked with
    //   the AlwaysProxy annotation, then we take methods from the class definition
    methodsCompiler.addMethods(clazz, defaultProxy);

    methodsCompiler.checkValid();
    methodsCompiler.removeSuperTypeMethods();

    // Load properties
    HashMap<String, ProxyEvent> events = new HashMap<String, ProxyEvent>();
    HashMap<String, ProxyProperty> properties = new HashMap<String, ProxyProperty>();
    Properties annoProperties = (Properties) clazz.getAnnotation(Properties.class);
    if (annoProperties != null) {
        for (Property anno : annoProperties.value()) {
            ProxyProperty property = new ProxyPropertyImpl(clazz, anno.value(), anno, annoProperties);
            properties.put(property.getName(), property);
            ProxyEvent event = property.getEvent();
            if (event != null)
                events.put(event.getName(), event);
        }
    }
    for (Field field : clazz.getDeclaredFields()) {
        Property anno = field.getAnnotation(Property.class);
        if (anno != null) {
            ProxyProperty property = new ProxyPropertyImpl(clazz,
                    anno.value().length() > 0 ? anno.value() : field.getName(), anno, annoProperties);
            properties.put(property.getName(), property);
            ProxyEvent event = property.getEvent();
            if (event != null)
                events.put(event.getName(), event);
        }
    }

    for (Method method : clazz.getDeclaredMethods()) {
        String name = method.getName();
        if (name.length() < 4 || !name.startsWith("get") || !Character.isUpperCase(name.charAt(3)))
            continue;
        Property anno = method.getAnnotation(Property.class);
        if (anno == null)
            continue;

        name = Character.toLowerCase(name.charAt(3)) + name.substring(4);
        if (properties.containsKey(name))
            continue;

        ProxyProperty property = new ProxyPropertyImpl(clazz, anno.value().length() > 0 ? anno.value() : name,
                anno, annoProperties);
        properties.put(property.getName(), property);
        ProxyEvent event = property.getEvent();
        if (event != null)
            events.put(event.getName(), event);
    }

    // Classes need to have all inherited properties added
    if (!clazz.isInterface()) {
        for (ProxyType ifc : interfaces)
            addProperties((ProxyTypeImpl) ifc, properties);
    }

    // Remove property accessors
    for (ProxyProperty prop : properties.values())
        methodsCompiler.removePropertyAccessors((ProxyPropertyImpl) prop);

    // Load events
    if (clazz.isAnnotationPresent(Events.class)) {
        Events annoEvents = (Events) clazz.getAnnotation(Events.class);
        for (Event annoEvent : annoEvents.value()) {
            if (!events.containsKey(annoEvent.value()))
                events.put(annoEvent.value(), new ProxyEvent(annoEvent));
        }
    }

    // Classes need to have all inherited events added
    if (!clazz.isInterface()) {
        for (ProxyType type : interfaces)
            addEvents((ProxyTypeImpl) type, events);
    }

    // Save
    this.properties = properties.isEmpty() ? null : properties;
    this.events = events.isEmpty() ? null : events;
    this.methods = methodsCompiler.toArray();
}

From source file:com.github.venkateshamurthy.designpatterns.builders.FluentBuilders.java

private Set<Method> getWritableNormalMethods(final Class<?> thisPojoClass) throws NotFoundException {
    final CtClass ctClass = ctPool.get(thisPojoClass.getName());
    final Set<CtMethod> ctMethodSet = new LinkedHashSet<>(); // Gets
                                                             // collected
    final Set<Method> methodSet = new LinkedHashSet<>(); // Gets collected

    final Set<Class<?>> propTypes = getPropertyClassTypes(thisPojoClass, ctClass, ctMethodSet);

    for (Method method : thisPojoClass.getDeclaredMethods()) {
        if (method.isSynthetic()) {
            LOGGER.warning(method.getName() + " is synthetically added, so ignoring");
            continue;
        }/*from  w  w  w.ja va2 s  .  c  o m*/
        if (Modifier.isPublic(method.getModifiers())
                && setMethodNamePattern.matcher(method.getName()).matches()) {
            methodSet.add(method);
        }
        final CtMethod ctMethod = ctClass.getDeclaredMethod(method.getName());
        if (Modifier.isPublic(method.getModifiers()) && setMethodNamePattern.matcher(method.getName()).matches()
                && !ctMethodSet.contains(ctMethod)) {

            // Make sure the types u get from method is really is of a field
            // type
            boolean isAdded = propTypes.containsAll(Arrays.asList(method.getParameterTypes()))
                    && ctMethodSet.add(ctMethod);
            if (!isAdded) {
                LOGGER.warning(method.getName() + " is not added");
            }
        }
    }
    return methodSet;
}

From source file:ca.uhn.fhir.jaxrs.server.AbstractJaxRsConformanceProvider.java

/**
 * This method will add a provider to the conformance. This method is almost an exact copy of {@link ca.uhn.fhir.rest.server.RestfulServer#findResourceMethods }
 * //from  ww w. ja  v  a  2 s  . c o  m
 * @param theProvider
 *           an instance of the provider interface
 * @param theProviderInterface
 *           the class describing the providers interface
 * @return the numbers of basemethodbindings added
 * @see ca.uhn.fhir.rest.server.RestfulServer#findResourceMethods
 */
public int addProvider(IResourceProvider theProvider, Class<? extends IResourceProvider> theProviderInterface)
        throws ConfigurationException {
    int count = 0;

    for (Method m : ReflectionUtil.getDeclaredMethods(theProviderInterface)) {
        BaseMethodBinding<?> foundMethodBinding = BaseMethodBinding.bindMethod(m, getFhirContext(),
                theProvider);
        if (foundMethodBinding == null) {
            continue;
        }

        count++;

        // if (foundMethodBinding instanceof ConformanceMethodBinding) {
        // myServerConformanceMethod = foundMethodBinding;
        // continue;
        // }

        if (!Modifier.isPublic(m.getModifiers())) {
            throw new ConfigurationException(
                    "Method '" + m.getName() + "' is not public, FHIR RESTful methods must be public");
        } else {
            if (Modifier.isStatic(m.getModifiers())) {
                throw new ConfigurationException(
                        "Method '" + m.getName() + "' is static, FHIR RESTful methods must not be static");
            } else {
                ourLog.debug("Scanning public method: {}#{}", theProvider.getClass(), m.getName());

                String resourceName = foundMethodBinding.getResourceName();
                ResourceBinding resourceBinding;
                if (resourceName == null) {
                    resourceBinding = myServerBinding;
                } else {
                    RuntimeResourceDefinition definition = getFhirContext().getResourceDefinition(resourceName);
                    if (myResourceNameToBinding.containsKey(definition.getName())) {
                        resourceBinding = myResourceNameToBinding.get(definition.getName());
                    } else {
                        resourceBinding = new ResourceBinding();
                        resourceBinding.setResourceName(resourceName);
                        myResourceNameToBinding.put(resourceName, resourceBinding);
                    }
                }

                List<Class<?>> allowableParams = foundMethodBinding.getAllowableParamAnnotations();
                if (allowableParams != null) {
                    for (Annotation[] nextParamAnnotations : m.getParameterAnnotations()) {
                        for (Annotation annotation : nextParamAnnotations) {
                            Package pack = annotation.annotationType().getPackage();
                            if (pack.equals(IdParam.class.getPackage())) {
                                if (!allowableParams.contains(annotation.annotationType())) {
                                    throw new ConfigurationException("Method[" + m.toString()
                                            + "] is not allowed to have a parameter annotated with "
                                            + annotation);
                                }
                            }
                        }
                    }
                }

                resourceBinding.addMethod(foundMethodBinding);
                ourLog.debug(" * Method: {}#{} is a handler", theProvider.getClass(), m.getName());
            }
        }
    }

    return count;
}

From source file:com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor.java

/**
 * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated {@link Reference @Reference} methods
 *
 * @param beanClass The {@link Class} of Bean
 * @return non-null {@link List}//from w w w.j av  a2s  . c  om
 */
private List<InjectionMetadata.InjectedElement> findMethodReferenceMetadata(final Class<?> beanClass) {

    final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();

    ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
        @Override
        public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {

            Method bridgedMethod = findBridgedMethod(method);

            if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }

            Reference reference = findAnnotation(bridgedMethod, Reference.class);

            if (reference != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
                if (Modifier.isStatic(method.getModifiers())) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("@Reference annotation is not supported on static methods: " + method);
                    }
                    return;
                }
                if (method.getParameterTypes().length == 0) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("@Reference  annotation should only be used on methods with parameters: "
                                + method);
                    }
                }
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
                elements.add(new ReferenceMethodElement(method, pd, reference));
            }
        }
    });

    return elements;

}

From source file:com.px100systems.util.serialization.SerializationDefinition.java

private SerializationDefinition(Class<?> cls) {
    definitions.put(cls, this);

    if (cls.getName().startsWith("java"))
        throw new RuntimeException("System classes are not supported: " + cls.getSimpleName());

    try {//from w w  w  .ja  va 2 s. c o  m
        constructor = cls.getConstructor();
    } catch (NoSuchMethodException e) {
        throw new RuntimeException("Missing no-arg constructor: " + cls.getSimpleName());
    }

    serializingSetter = ReflectionUtils.findMethod(cls, "setSerializing", boolean.class);

    for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
        for (Field field : c.getDeclaredFields()) {
            if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers()))
                continue;

            FieldDefinition fd = new FieldDefinition();
            fd.name = field.getName();

            fd.type = field.getType();
            if (fd.type.isPrimitive())
                throw new RuntimeException("Primitives are not supported: " + fd.type.getSimpleName());

            Calculated calc = field.getAnnotation(Calculated.class);

            if (!fd.type.equals(Integer.class) && !fd.type.equals(Long.class) && !fd.type.equals(Double.class)
                    && !fd.type.equals(Boolean.class) && !fd.type.equals(Date.class)
                    && !fd.type.equals(String.class))
                if (fd.type.equals(List.class) || fd.type.equals(Set.class)) {
                    SerializedCollection sc = field.getAnnotation(SerializedCollection.class);
                    if (sc == null)
                        throw new RuntimeException(
                                cls.getSimpleName() + "." + fd.name + " is missing @SerializedCollection");

                    if (calc != null)
                        throw new RuntimeException(cls.getSimpleName() + "." + fd.name
                                + " cannot have a calculator because it is a collection");

                    fd.collectionType = sc.type();
                    fd.primitive = fd.collectionType.equals(Integer.class)
                            || fd.collectionType.equals(Long.class) || fd.collectionType.equals(Double.class)
                            || fd.collectionType.equals(Boolean.class) || fd.collectionType.equals(Date.class)
                            || fd.collectionType.equals(String.class);
                    if (!fd.primitive) {
                        if (cls.getName().startsWith("java"))
                            throw new RuntimeException(cls.getSimpleName() + "." + fd.name
                                    + ": system collection types are not supported: "
                                    + fd.collectionType.getSimpleName());

                        if (!definitions.containsKey(fd.collectionType))
                            new SerializationDefinition(fd.collectionType);
                    }
                } else {
                    if (cls.getName().startsWith("java"))
                        throw new RuntimeException(
                                "System classes are not supported: " + fd.type.getSimpleName());

                    if (!definitions.containsKey(fd.type))
                        new SerializationDefinition(fd.type);
                }
            else
                fd.primitive = true;

            try {
                fd.accessor = c.getMethod(PropertyAccessor.methodName("get", fd.name));
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(cls.getSimpleName() + "." + fd.name + " is missing getter");
            }

            try {
                fd.mutator = c.getMethod(PropertyAccessor.methodName("set", fd.name), fd.type);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(cls.getSimpleName() + "." + fd.name + " is missing setter");
            }

            if (calc != null)
                fd.calculator = new SpelExpressionParser().parseExpression(calc.value());

            fields.add(fd);
        }

        for (Method method : c.getDeclaredMethods())
            if (Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())
                    && method.getName().startsWith("get")
                    && method.isAnnotationPresent(SerializedGetter.class)) {
                FieldDefinition fd = new FieldDefinition();
                fd.name = method.getName().substring(3);
                fd.name = fd.name.substring(0, 1).toLowerCase() + fd.name.substring(1);
                fd.type = method.getReturnType();
                fd.primitive = fd.type != null && (fd.type.equals(Integer.class) || fd.type.equals(Long.class)
                        || fd.type.equals(Double.class) || fd.type.equals(Boolean.class)
                        || fd.type.equals(Date.class) || fd.type.equals(String.class));

                if (!fd.primitive)
                    throw new RuntimeException("Not compact-serializable getter type: "
                            + (fd.type == null ? "void" : fd.type.getSimpleName()));

                fd.accessor = method;
                gettersOnly.add(fd);
            }
    }
}