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

org.smooks.cartridges.javabean.BeanRuntimeInfo Maven / Gradle / Ivy

The newest version!
/*-
 * ========================LICENSE_START=================================
 * smooks-javabean-cartridge
 * %%
 * Copyright (C) 2020 Smooks
 * %%
 * Licensed under the terms of the Apache License Version 2.0, or
 * the GNU Lesser General Public License version 3.0 or later.
 *
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-or-later
 *
 * ======================================================================
 *
 * Licensed 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.
 *
 * ======================================================================
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * =========================LICENSE_END==================================
 */
package org.smooks.cartridges.javabean;

import org.smooks.api.ApplicationContext;
import org.smooks.api.SmooksConfigException;
import org.smooks.support.ClassUtils;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Java bean runtime info.
 *
 * @author [email protected]
 */
public class BeanRuntimeInfo {

    protected static final String CONTEXT_KEY = BeanRuntimeInfo.class.getName() + "#CONTEXT_KEY";

    /**
     * The basic type that's created and populated for the associated bean.
     */
    protected Class populateType;

    /**
     * The bean classification.
     * 

* We maintain this classification enum because it helps us avoid performing * instanceof checks, which are cheap when the instance being checked is * an instanceof, but is expensive if it's not. */ protected Classification classification; /** * If the bean classification is an ARRAY_COLLECTION, this member specifies the * actual array type. */ protected Class arrayType; /** * Is the type a JAXB Type. */ protected boolean isJAXBType = false; /** * Bean type classification. *

* We maintain this classification enum because it helps us avoid performing * instanceof checks, which are cheap when the instance being checked is * an instanceof, but expensive if it's not. */ public enum Classification { NON_COLLECTION, ARRAY_COLLECTION, COLLECTION_COLLECTION, MAP_COLLECTION, } public BeanRuntimeInfo() { } public BeanRuntimeInfo(Class clazz) { resolveBeanRuntimeInfo(clazz); } public BeanRuntimeInfo(String classname) { resolveBeanRuntimeInfo(classname); } public static void recordBeanRuntimeInfo(String beanId, BeanRuntimeInfo beanRuntimeInfo, ApplicationContext appContext) { Map runtimeInfoMap = getRuntimeInfoMap(appContext); BeanRuntimeInfo existingBeanConfig = runtimeInfoMap.get(beanId); if (existingBeanConfig != null && !beanRuntimeInfo.equals(existingBeanConfig)) { throw new SmooksConfigException("Multiple configurations present with beanId='" + beanId + "', but the bean runtime infos are not equal i.e bean classes etc are different. Use a different beanId and the 'setOnMethod' config if needed."); } runtimeInfoMap.put(beanId, beanRuntimeInfo); } public static BeanRuntimeInfo getBeanRuntimeInfo(String beanId, ApplicationContext appContext) { Map runtimeInfoMap = getRuntimeInfoMap(appContext); return runtimeInfoMap.get(beanId); } public void setClassification(Class clazz) { // We maintain a targetType enum because it helps us avoid performing // instanceof checks, which are cheap when the instance being checked is // an instanceof, but is expensive if it's not.... if (Map.class.isAssignableFrom(clazz)) { this.setClassification(Classification.MAP_COLLECTION); } else if (Collection.class.isAssignableFrom(clazz)) { this.setClassification(Classification.COLLECTION_COLLECTION); } else { this.setClassification(Classification.NON_COLLECTION); } } public static BeanRuntimeInfo getBeanRuntimeInfo(String beanId, String beanClassName, ApplicationContext appContext) { Map runtimeInfoMap = getRuntimeInfoMap(appContext); BeanRuntimeInfo beanRuntimeInfo = runtimeInfoMap.get(beanId); if (beanRuntimeInfo == null) { beanRuntimeInfo = new BeanRuntimeInfo(beanClassName); recordBeanRuntimeInfo(beanId, beanRuntimeInfo, appContext); } return beanRuntimeInfo; } /** * Resolve the Javabean runtime class. *

* Also performs some checks on the bean. * * @param beanClass The beanClass name. * @return The bean runtime class instance. */ protected void resolveBeanRuntimeInfo(String beanClass) { Class clazz; // If it's an array, we use a List and extract an array from it on the // visitAfter event.... if (beanClass.endsWith("[]")) { this.setClassification(BeanRuntimeInfo.Classification.ARRAY_COLLECTION); String arrayTypeName = beanClass.substring(0, beanClass.length() - 2); try { this.setArrayType(ClassUtils.forName(arrayTypeName, getClass())); } catch (ClassNotFoundException e) { throw new SmooksConfigException("Invalid Smooks bean configuration. Bean class " + arrayTypeName + " not on classpath."); } this.setPopulateType(ArrayList.class); } else { try { clazz = ClassUtils.forName(beanClass, getClass()); } catch (ClassNotFoundException e) { throw new SmooksConfigException("Invalid Smooks bean configuration. Bean class " + beanClass + " not on classpath."); } this.setPopulateType(clazz); this.setClassification(clazz); } } protected void resolveBeanRuntimeInfo(Class clazz) { // If it's an array, we use a List and extract an array from it on the // visitAfter event.... if (clazz.isArray()) { this.setClassification(BeanRuntimeInfo.Classification.ARRAY_COLLECTION); this.setArrayType(clazz.getComponentType()); this.setPopulateType(ArrayList.class); } else { this.setPopulateType(clazz); this.setClassification(clazz); } } @SuppressWarnings("unchecked") protected static Map getRuntimeInfoMap(ApplicationContext appContext) { Map runtimeInfoMap = (Map) appContext.getRegistry().lookup(CONTEXT_KEY); if (runtimeInfoMap == null) { runtimeInfoMap = new HashMap<>(); appContext.getRegistry().registerObject(CONTEXT_KEY, runtimeInfoMap); } return runtimeInfoMap; } public Class getPopulateType() { return populateType; } public void setPopulateType(Class populateType) { this.populateType = populateType; // Check the annotations and see if one of them is the XmlType annotation. Can't use // a type check because XmlType is not in Java5, so need to do a physical name check... for (Annotation anno : populateType.getAnnotations()) { isJAXBType = anno.annotationType().getName().equals("javax.xml.bind.annotation.XmlType"); if (isJAXBType) { break; } } } public Classification getClassification() { return classification; } public void setClassification(Classification classification) { this.classification = classification; } public Class getArrayType() { return arrayType; } public void setArrayType(Class arrayType) { this.arrayType = arrayType; } public boolean isJAXBType() { return isJAXBType; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } if (!(obj instanceof BeanRuntimeInfo)) { return false; } BeanRuntimeInfo beanInfo = (BeanRuntimeInfo) obj; if (beanInfo.getArrayType() != getArrayType()) { return false; } if (beanInfo.getClassification() != getClassification()) { return false; } if (beanInfo.getPopulateType() != getPopulateType()) { return false; } return true; } public String toString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("Classification: " + classification); stringBuilder.append(", Populate Type: : " + populateType.getName()); if (arrayType != null) { stringBuilder.append(", Array Type: " + arrayType.getName()); } return stringBuilder.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy