com.citytechinc.cq.component.dialog.util.DialogUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.citytechinc.cq.component.dialog.util.DialogUtil.java

Source

/**
 *    Copyright 2013 CITYTECH, Inc.
 *
 *    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.
 */
package com.citytechinc.cq.component.dialog.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMember;
import javassist.CtMethod;
import javassist.NotFoundException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.codehaus.plexus.util.StringUtils;

import com.citytechinc.cq.component.annotations.DialogField;
import com.citytechinc.cq.component.annotations.DialogFieldOverride;
import com.citytechinc.cq.component.annotations.Property;
import com.citytechinc.cq.component.annotations.Listener;
import com.citytechinc.cq.component.dialog.ComponentNameTransformer;
import com.citytechinc.cq.component.dialog.Dialog;
import com.citytechinc.cq.component.dialog.DialogFieldConfig;
import com.citytechinc.cq.component.dialog.exception.InvalidComponentClassException;
import com.citytechinc.cq.component.dialog.exception.InvalidComponentFieldException;
import com.citytechinc.cq.component.dialog.exception.OutputFailureException;
import com.citytechinc.cq.component.dialog.factory.DialogFactory;
import com.citytechinc.cq.component.dialog.widget.WidgetRegistry;
import com.citytechinc.cq.component.maven.util.ComponentMojoUtil;

public class DialogUtil {
    private DialogUtil() {
    };

    /**
     * Writes a dialog.xml file, the path of which being based on the component
     * Class.
     * 
     * @param dialog
     * @param componentClass
     * @return The written file
     * @throws OutputFailureException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws TransformerException
     * @throws ClassNotFoundException
     * @throws IllegalArgumentException
     * @throws SecurityException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    public static File writeDialogToFile(ComponentNameTransformer transformer, Dialog dialog,
            CtClass componentClass, File buildDirectory, String componentPathBase,
            String defaultComponentPathSuffix) throws OutputFailureException, IOException,
            ParserConfigurationException, TransformerException, ClassNotFoundException, IllegalArgumentException,
            SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {

        return ComponentMojoUtil.writeElementToFile(transformer, dialog, componentClass, buildDirectory,
                componentPathBase, defaultComponentPathSuffix, dialog.getFileName());

    }

    /**
     * Writes a provided dialog file to a provided archive output stream at a
     * path determined by the class of the component.
     * 
     * @param dialogFile
     * @param componentClass
     * @param archiveStream
     * @param reservedNames A list of files which already exist within the Zip
     *            Archive. If a dialog.xml file already exists for a particular
     *            component, it is left untouched.
     * @param componentPathBase
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static void writeDialogToArchiveFile(ComponentNameTransformer transformer, File dialogFile,
            CtClass componentClass, ZipArchiveOutputStream archiveStream, Set<String> reservedNames,
            String componentPathBase, String defaultComponentPathSuffix)
            throws IOException, ClassNotFoundException {

        ComponentMojoUtil.writeElementToArchiveFile(transformer, dialogFile, componentClass, archiveStream,
                reservedNames, componentPathBase, defaultComponentPathSuffix, "/" + dialogFile.getName());
    }

    /**
     * Constructs a list of Dialog objects based on Classes annotated by
     * Component annotations. Scans the provided list of classes constructing a
     * Dialog object for each one annotated with the Component annotation. Any
     * classes provided in the class list which are not thusly annotated are
     * ignored.
     * 
     * @param classList
     * @param zipOutputStream
     * @param reservedNames
     * @param classLoader
     * @param classPool
     * @return A list of constructed Dialog objects
     * @throws InvalidComponentClassException
     * @throws InvalidComponentFieldException
     * @throws OutputFailureException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws TransformerException
     * @throws ClassNotFoundException
     * @throws CannotCompileException
     * @throws NotFoundException
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     */
    public static List<Dialog> buildDialogsFromClassList(ComponentNameTransformer transformer,
            List<CtClass> classList, ZipArchiveOutputStream zipOutputStream, Set<String> reservedNames,
            WidgetRegistry widgetRegistry, ClassLoader classLoader, ClassPool classPool, File buildDirectory,
            String componentPathBase, String defaultComponentPathSuffix) throws InvalidComponentClassException,
            InvalidComponentFieldException, OutputFailureException, IOException, ParserConfigurationException,
            TransformerException, ClassNotFoundException, CannotCompileException, NotFoundException,
            SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, NoSuchMethodException, InstantiationException {

        final List<Dialog> dialogList = new ArrayList<Dialog>();

        for (CtClass curClass : classList) {

            ComponentMojoUtil.getLog().debug("Processing Component Class " + curClass);
            Dialog builtDialog = DialogFactory.make(curClass, widgetRegistry, classLoader, classPool);
            dialogList.add(builtDialog);
            File dialogFile = writeDialogToFile(transformer, builtDialog, curClass, buildDirectory,
                    componentPathBase, defaultComponentPathSuffix);
            writeDialogToArchiveFile(transformer, dialogFile, curClass, zipOutputStream, reservedNames,
                    componentPathBase, defaultComponentPathSuffix);
            dialogList.add(builtDialog);
        }

        return dialogList;

    }

    private static CtMember getMemberForAnnotatedInterfaceMethod(CtMethod member)
            throws InvalidComponentClassException, ClassNotFoundException, NotFoundException {
        CtMethod newMember = null;
        List<CtClass> interfaces = new ArrayList<CtClass>();
        CtClass clazz = member.getDeclaringClass();
        while (clazz != null) {
            interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
            clazz = clazz.getSuperclass();
        }
        for (CtClass ctclass : interfaces) {
            try {
                CtMethod newMethodMember = ctclass.getDeclaredMethod(member.getName(), member.getParameterTypes());
                DialogField tempDialogProperty = (DialogField) newMethodMember.getAnnotation(DialogField.class);
                if (tempDialogProperty != null) {
                    if (newMember == null) {
                        newMember = newMethodMember;
                    } else {
                        throw new InvalidComponentClassException(
                                "Class has multiple interfaces that have the same method signature annotated");
                    }
                }
            } catch (NotFoundException e) {
            }
        }
        if (newMember != null) {
            member = newMember;
        }
        return newMember;
    }

    public static DialogFieldConfig getDialogFieldFromSuperClasses(CtMethod method)
            throws NotFoundException, ClassNotFoundException, InvalidComponentClassException {
        DialogFieldConfig dialogFieldConfig = null;
        List<CtClass> classes = new ArrayList<CtClass>();
        CtClass clazz = method.getDeclaringClass();
        classes.add(clazz);
        while (clazz.getSuperclass() != null) {
            classes.add(clazz.getSuperclass());
            clazz = clazz.getSuperclass();
        }
        Collections.reverse(classes);
        CtMember interfaceMember = getMemberForAnnotatedInterfaceMethod(method);
        if (interfaceMember != null) {
            dialogFieldConfig = new DialogFieldConfig(
                    (DialogField) interfaceMember.getAnnotation(DialogField.class), interfaceMember);
        }
        for (CtClass ctclass : classes) {
            try {
                CtMethod superClassMethod = ctclass.getDeclaredMethod(method.getName(), method.getParameterTypes());
                if (superClassMethod.hasAnnotation(DialogField.class)) {
                    dialogFieldConfig = new DialogFieldConfig(
                            (DialogField) superClassMethod.getAnnotation(DialogField.class), superClassMethod);
                } else if (superClassMethod.hasAnnotation(DialogFieldOverride.class)) {
                    mergeDialogFields(dialogFieldConfig, superClassMethod);
                }
            } catch (NotFoundException e) {
            }
        }
        return dialogFieldConfig;
    }

    private static void mergeDialogFields(DialogFieldConfig dialogFieldConfig, CtMethod method)
            throws ClassNotFoundException {
        if (dialogFieldConfig != null && method.hasAnnotation(DialogFieldOverride.class)) {
            DialogFieldOverride dialogField = (DialogFieldOverride) method.getAnnotation(DialogFieldOverride.class);
            if (StringUtils.isNotEmpty(dialogField.fieldLabel())) {
                dialogFieldConfig.setFieldLabel(dialogField.fieldLabel());
            }

            if (StringUtils.isNotEmpty(dialogField.fieldDescription())) {
                dialogFieldConfig.setFieldDescription(dialogField.fieldDescription());
            }

            dialogFieldConfig.setRequired(dialogField.required());

            dialogFieldConfig.setHideLabel(dialogField.hideLabel());

            if (StringUtils.isNotEmpty(dialogField.defaultValue())) {
                dialogFieldConfig.setDefaultValue(dialogField.defaultValue());
            }

            if (StringUtils.isNotEmpty(dialogField.name())) {
                dialogFieldConfig.setName(dialogField.name());
            }

            dialogFieldConfig.setTab(dialogField.tab());

            dialogFieldConfig.setRanking(dialogField.ranking());

            if (dialogField.additionalProperties().length > 0) {
                List<Property> properties = new ArrayList<Property>();
                properties.addAll(Arrays.asList(dialogField.additionalProperties()));
                if (dialogField.mergeAdditionalProperties()) {
                    properties.addAll(Arrays.asList(dialogFieldConfig.getAdditionalProperties()));
                }
                dialogFieldConfig.setAdditionalProperties(properties.toArray(new Property[properties.size()]));
            }

            if (dialogField.listeners().length > 0) {
                List<Listener> listeners = new ArrayList<Listener>();
                listeners.addAll(Arrays.asList(dialogField.listeners()));
                if (dialogField.mergeAdditionalProperties()) {
                    listeners.addAll(Arrays.asList(dialogFieldConfig.getListeners()));
                }
                dialogFieldConfig.setListeners(listeners.toArray(new Listener[listeners.size()]));
            }

            if (StringUtils.isNotBlank(dialogField.title())) {
                dialogFieldConfig.setTitle(dialogField.title());
            }

            if (StringUtils.isNotBlank(dialogField.value())) {
                dialogFieldConfig.setValue(dialogField.value());
            }

            dialogFieldConfig.setDisabled(dialogField.disabled());

            if (StringUtils.isNotBlank(dialogField.cssClass())) {
                dialogFieldConfig.setCssClass(dialogField.cssClass());
            }

            dialogFieldConfig.setSuppressTouchUI(dialogField.suppressTouchUI());
        }

    }
}