All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.io.pof.reflect.internal.AnnotationVisitor Maven / Gradle / Ivy

There is a newer version: 24.03
Show newest version
/*
 * Copyright (c) 2000, 2020, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */
package com.tangosol.io.pof.reflect.internal;

import com.tangosol.io.pof.annotation.Portable;
import com.tangosol.io.pof.annotation.PortableProperty;

import com.tangosol.io.pof.reflect.Codec;
import com.tangosol.io.pof.reflect.Codecs;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import java.util.HashSet;
import java.util.Set;

/**
 * An AnnotationVisitor is a {@link Visitor} implementation that injects
 * information obtained by inspecting a provided class into a
 * {@link ClassMetadataBuilder}. The modified builder will then realize a
 * {@link TypeMetadata} instance with this injected information.
 * 

* This implementation is responsible purely for injecting explicitly defined * information in the form of annotations. It depends upon, and hence is * aware of, only the following annotations: *

    *
  • {@link Portable}
  • *
  • {@link PortableProperty}
  • *
*

* This class has two strategies of metadata discovery - field and accessor - * inspected respectively. Duplication is deemed by the same name derived by * {@link NameMangler} implementations. * * @author hr * * @param the type this AnnotationVisitor will be inspecting * * @since 3.7.1 */ public class AnnotationVisitor implements Visitor> { // ----- constructors --------------------------------------------------- /** * Construct an AnnotationVisitor instance */ public AnnotationVisitor() { this(false); } /** * Construct an AnnotationVisitor instance specifying whether to use * auto-indexing * * @param fAutoIndex whether to enable auto-indexing */ public AnnotationVisitor(boolean fAutoIndex) { this.m_fAutoIndex = fAutoIndex; } // ----- Visitor interface ---------------------------------------------- /** * {@inheritDoc} */ public void visit(ClassMetadataBuilder builder, Class clz) { Portable portable = clz.getAnnotation(Portable.class); // fast escape switch if (portable == null) { return; } // get header level information boolean fAutoIndex = m_fAutoIndex; builder.setClass((Class) clz); // get field level information Field[] aFields = clz.getDeclaredFields(); Set listFieldsExcluded = new HashSet(aFields.length); for (int i = 0; i < aFields.length; ++i) { Field field = aFields[i]; PortableProperty attribute = field.getAnnotation(PortableProperty.class); if (attribute == null) { continue; } String sFieldName = field.getName(); Class clzField = field.getType(); String sMangledName = NameManglers.FIELD_MANGLER.mangle(sFieldName); Codec codec = Codecs.getCodec(attribute.codec()); if (!fAutoIndex && attribute.value() < 0) { throw new IllegalArgumentException("A POF Index must be specified for the property " + clz.getName()+"#"+sFieldName+" by specifying " + "within the annotation or enabling autoIndexing on the " + "Portable annotation"); } builder.addAttribute( builder.newAttribute() .setName(sMangledName) .setCodec(codec) .setInvocationStrategy(new InvocationStrategies.FieldInvocationStrategy(field)) .setIndex(attribute.value()).build()); // field level annotations take precedence over accessor // annotations listFieldsExcluded.add(sMangledName); } // get method level information Method[] aMethods = clz.getDeclaredMethods(); for (int i = 0; i < aMethods.length; ++i) { Method method = aMethods[i]; PortableProperty attribute = method.getAnnotation(PortableProperty.class); if (attribute == null) { continue; } String sMethodName = method.getName(); if (sMethodName.startsWith("get") || sMethodName.startsWith("set") || sMethodName.startsWith("is")) { String sName = NameManglers.METHOD_MANGLER.mangle(sMethodName); if (listFieldsExcluded.contains(sName)) { continue; } InvocationStrategies.MethodInvocationStrategy strategy = new InvocationStrategies.MethodInvocationStrategy(method); Codec codec = Codecs.getCodec(attribute.codec()); if (!fAutoIndex && attribute.value() < 0) { throw new IllegalArgumentException("A POF Index must be specified for the method " + clz.getName() + "#" + sMethodName + " by specifying " + "within the annotation or enabling autoIndexing on the " + "Portable annotation"); } builder.addAttribute( builder.newAttribute() .setName(sName) .setCodec(codec) .setInvocationStrategy(strategy) .setIndex(attribute.value()).build()); // in the case where both accessors (getters and setters) are // annotated we only use the values in the first annotation // we encounter listFieldsExcluded.add(sName); } } } // ----- data members --------------------------------------------------- /** * Whether to use the auto-indexing feature to derive indexes */ private final boolean m_fAutoIndex; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy