Package org.apache.geronimo.j2ee.deployment.annotation

Source Code of org.apache.geronimo.j2ee.deployment.annotation.PersistenceContextAnnotationHelper

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.apache.geronimo.j2ee.deployment.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContexts;
import javax.persistence.PersistenceContextType;
import javax.persistence.PersistenceProperty;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.xbeans.javaee6.InjectionTargetType;
import org.apache.geronimo.xbeans.javaee6.JndiNameType;
import org.apache.geronimo.xbeans.javaee6.PersistenceContextRefType;
import org.apache.geronimo.xbeans.javaee6.PersistenceContextTypeType;
import org.apache.geronimo.xbeans.javaee6.PropertyType;
import org.apache.geronimo.xbeans.javaee6.XsdStringType;
import org.apache.xbean.finder.ClassFinder;


/**
* Static helper class used to encapsulate all the functions related to the translation of
* <strong>@PersistenceContext</strong> and <strong>@PersistenceContexts</strong> annotations to deployment
* descriptor tags. The PersistenceContextAnnotationHelper class can be used as part of the deployment of
* a module into the Geronimo server. It performs the following major functions:
* <p/>
* <ol>
* <li>Translates annotations into corresponding deployment descriptor elements (so that the
* actual deployment descriptor in the module can be updated or even created if necessary)
* </ol>
* <p/>
* <p><strong>Note(s):</strong>
* <ul>
* <li>The user is responsible for invoking change to metadata-complete
* <li>This helper class will validate any changes it makes to the deployment descriptor. An
* exception will be thrown if it fails to parse
* </ul>
* <p/>
* <p><strong>Remaining ToDo(s):</strong>
* <ul>
* <li>None
* </ul>
*
* @version $Rev $Date: 2010-02-03 02:26:50 -0500 (Wed, 03 Feb 2010) $
*
*/
public final class PersistenceContextAnnotationHelper extends AnnotationHelper {

    // Private instance variables
    private static final Logger log = LoggerFactory.getLogger(PersistenceContextAnnotationHelper.class);

    // Private constructor to prevent instantiation
    private PersistenceContextAnnotationHelper() {
    }

    /**
     * Update the deployment descriptor from the PersistenceContext and PersistenceContexts annotations
     *
     * @param annotatedApp Access to the spec dd
     * @param classFinder Access to the classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    public static void processAnnotations(AnnotatedApp annotatedApp, ClassFinder classFinder) throws DeploymentException {
        if (annotatedApp != null) {
            if (classFinder.isAnnotationPresent(PersistenceContexts.class)) {
                processPersistenceContexts(annotatedApp, classFinder);
            }
            if (classFinder.isAnnotationPresent(PersistenceContext.class)) {
                processPersistenceContext(annotatedApp, classFinder);
            }
        }
    }


    /**
     * Process annotations
     *
     * @param annotatedApp Access to the spec dd
     * @param classFinder Access to the classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    private static void processPersistenceContext(AnnotatedApp annotatedApp, ClassFinder classFinder) throws DeploymentException {
        log.debug("processPersistenceContext(): Entry: AnnotatedApp: " + annotatedApp.toString());

        List<Class> classeswithPersistenceContext = classFinder.findAnnotatedClasses(PersistenceContext.class);
        List<Method> methodswithPersistenceContext = classFinder.findAnnotatedMethods(PersistenceContext.class);
        List<Field> fieldswithPersistenceContext = classFinder.findAnnotatedFields(PersistenceContext.class);

        // Class-level annotation
        for (Class cls : classeswithPersistenceContext) {
            PersistenceContext persistenceContext = (PersistenceContext) cls.getAnnotation(PersistenceContext.class);
            if (persistenceContext != null) {
                addPersistenceContext(annotatedApp, persistenceContext, cls, null, null);
            }
        }

        // Method-level annotation
        for (Method method : methodswithPersistenceContext) {
            PersistenceContext persistenceContext = method.getAnnotation(PersistenceContext.class);
            if (persistenceContext != null) {
                addPersistenceContext(annotatedApp, persistenceContext, null, method, null);
            }
        }

        // Field-level annotation
        for (Field field : fieldswithPersistenceContext) {
            PersistenceContext persistenceContext = field.getAnnotation(PersistenceContext.class);
            if (persistenceContext != null) {
                addPersistenceContext(annotatedApp, persistenceContext, null, null, field);
            }
        }

        // Validate deployment descriptor to ensure it's still okay
        validateDD(annotatedApp);

        log.debug("processPersistenceContext(): Exit: AnnotatedApp: " + annotatedApp.toString());
    }


    /**
     * Process multiple annotations
     *
     * @param annotatedApp Access to the spec dd
     * @param classFinder Access to the classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    private static void processPersistenceContexts(AnnotatedApp annotatedApp, ClassFinder classFinder) throws DeploymentException {
        log.debug("processPersistenceContexts(): Entry");

        List<Class> classeswithPersistenceContexts = classFinder.findAnnotatedClasses(PersistenceContexts.class);

        // Class-level annotation(s)
        List<PersistenceContext> persistenceContextList = new ArrayList<PersistenceContext>();
        for (Class cls : classeswithPersistenceContexts) {
            PersistenceContexts persistenceContexts = (PersistenceContexts) cls.getAnnotation(PersistenceContexts.class);
            if (persistenceContexts != null) {
                persistenceContextList.addAll(Arrays.asList(persistenceContexts.value()));
            }
            for (PersistenceContext persistenceContext : persistenceContextList) {
                addPersistenceContext(annotatedApp, persistenceContext, cls, null, null);
            }
            persistenceContextList.clear();
        }

        log.debug("processPersistenceContexts(): Exit");
    }


    /**
     * Add @PersistenceContext and @PersistenceContexts annotations to the deployment descriptor. XMLBeans are used to
     * read and manipulate the deployment descriptor as necessary. The PersistenceContext annotation(s) will be
     * converted to one of the following deployment descriptors:
     *
     * <ol>
     *      <li><persistence-context-ref> -- Describes a single container-managed entity manager
     * </ol>
     *
     * <p><strong>Note(s):</strong>
     * <ul>
     *      <li>The deployment descriptor is the authoritative source so this method ensures that
     *          existing elements in it are not overwritten by annoations
     * </ul>
     *
     * @param annotation @PersistenceContext annotation
     * @param cls        Class name with the @PersistenceContext annoation
     * @param method     Method name with the @PersistenceContext annoation
     * @param field      Field name with the @PersistenceContext annoation
     * @param annotatedApp  Access to the specc dd
     */
    private static void addPersistenceContext(AnnotatedApp annotatedApp, PersistenceContext annotation, Class cls, Method method, Field field) {
        log.debug("addPersistenceContext( [annotatedApp] " + annotatedApp.toString() + "," + '\n' +
                "[annotation] " + annotation.toString() + "," + '\n' +
                "[cls] " + (cls != null ? cls.getName() : null) + "," + '\n' +
                "[method] " + (method != null ? method.getName() : null) + "," + '\n' +
                "[field] " + (field != null ? field.getName() : null) + " ): Entry");

        //------------------------------------------------------------------------------------------
        // PersistenceContextRef name:
        // -- When annotation is applied on a class:    Name must be provided (cannot be inferred)
        // -- When annotation is applied on a method:   Name is JavaBeans property name qualified
        //                                              by the class (or as provided on the
        //                                              annotation)
        // -- When annotation is applied on a field:    Name is the field name qualified by the
        //                                              class (or as provided on the annotation)
        //------------------------------------------------------------------------------------------
        String persistenceContextRefName = getName(annotation.name(), method, field);

        log.debug("addPersistenceContext(): PersistenceContextRefName: " + persistenceContextRefName);

        // If there is already xml for the persistence context ref, just add injection targets and return.
        PersistenceContextRefType[] persistenceContextRefs = annotatedApp.getPersistenceContextRefArray();
        for (PersistenceContextRefType persistenceContextRef : persistenceContextRefs) {
            if (persistenceContextRef.getPersistenceContextRefName().getStringValue().trim().equals(persistenceContextRefName)) {
                if (method != null || field != null) {
                    InjectionTargetType[] targets = persistenceContextRef.getInjectionTargetArray();
                    if (!hasTarget(method, field, targets)) {
                        configureInjectionTarget(persistenceContextRef.addNewInjectionTarget(), method, field);
                    }
                }
                return;
            }
        }

        // Doesn't exist in deployment descriptor -- add new
        PersistenceContextRefType persistenceContextRef = annotatedApp.addNewPersistenceContextRef();

        //------------------------------------------------------------------------------
        // <persistence-context-ref> required elements:
        //------------------------------------------------------------------------------

        // persistence-context-ref-name
        JndiNameType unitRefName = persistenceContextRef.addNewPersistenceContextRefName();
        unitRefName.setStringValue(persistenceContextRefName);

        //------------------------------------------------------------------------------
        // <persistence-context-ref> optional elements:
        //------------------------------------------------------------------------------

        // persistence-unit-name
        String unitNameAnnotation = annotation.unitName();
        if (!unitNameAnnotation.equals("")) {
            org.apache.geronimo.xbeans.javaee6.String persistenceUnitName = persistenceContextRef.addNewPersistenceUnitName();
            persistenceUnitName.setStringValue(unitNameAnnotation);
        }

        // persistence-context-type
        if (annotation.type() == PersistenceContextType.TRANSACTION) {
            PersistenceContextTypeType persistenceContextType = persistenceContextRef.addNewPersistenceContextType();
            persistenceContextType.setStringValue("Transaction");
            persistenceContextRef.setPersistenceContextType(persistenceContextType);
        } else if (annotation.type() == PersistenceContextType.EXTENDED) {
            PersistenceContextTypeType persistenceContextType = persistenceContextRef.addNewPersistenceContextType();
            persistenceContextType.setStringValue("Extended");
            persistenceContextRef.setPersistenceContextType(persistenceContextType);
        }

        // persistence-context-properties
        PersistenceProperty[] properties = annotation.properties();
        for (PersistenceProperty property : properties) {
            PropertyType propertyType = persistenceContextRef.addNewPersistenceProperty();
            XsdStringType propertyName = propertyType.addNewName();
            propertyName.setStringValue(property.name());
            XsdStringType propertyValue = propertyType.addNewValue();
            propertyValue.setStringValue(property.value());
        }

        // injection targets
        if (method != null || field != null) {
            configureInjectionTarget(persistenceContextRef.addNewInjectionTarget(), method, field);
        }

    }

}
TOP

Related Classes of org.apache.geronimo.j2ee.deployment.annotation.PersistenceContextAnnotationHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.