org.artificer.common.ArtifactType.java Source code

Java tutorial

Introduction

Here is the source code for org.artificer.common.ArtifactType.java

Source

/*
 * Copyright 2012 JBoss 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 org.artificer.common;

import org.apache.commons.lang.StringUtils;
import org.artificer.common.i18n.Messages;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.Artifact;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactEnum;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactType;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.DocumentArtifactType;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.ExtendedArtifactType;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.ExtendedDocument;

import java.io.Serializable;
import java.lang.reflect.Method;

/**
 * A class representing all of the Artifact Types defined by S-RAMP.
 *
 * @author eric.wittmann@redhat.com
 */
public class ArtifactType implements Serializable {

    /**
     * Returns true if the given artifact type is valid.  It must be alphanumeric only.
     * @param artifactType the artifact type
     * @return true if valid
     */
    public static final boolean isValid(String artifactType) {
        for (int i = 0; i < artifactType.length(); i++) {
            char c = artifactType.charAt(i);
            if (!(Character.isLetter(c) || Character.isDigit(c))) {
                return false;
            }
        }
        return true;
    }

    public static final ArtifactType Document() {
        return new ArtifactType(ArtifactTypeEnum.Document, "application/octet-stream");
    }

    public static final ArtifactType Document(String mimeType) {
        return new ArtifactType(ArtifactTypeEnum.Document, mimeType);
    }

    public static final ArtifactType XmlDocument() {
        return new ArtifactType(ArtifactTypeEnum.XmlDocument, "application/xml");
    }

    public static final ArtifactType XsdDocument() {
        return new ArtifactType(ArtifactTypeEnum.XsdDocument, "application/xml");
    }

    public static final ArtifactType WsdlDocument() {
        return new ArtifactType(ArtifactTypeEnum.WsdlDocument, "application/xml");
    }

    public static final ArtifactType PolicyDocument() {
        return new ArtifactType(ArtifactTypeEnum.PolicyDocument, "application/xml");
    }

    public static final ArtifactType ExtendedArtifactType(String extendedType) {
        return ExtendedArtifactType(extendedType, false);
    }

    public static final ArtifactType ExtendedArtifactType(String extendedType, boolean derived) {
        ArtifactType at = new ArtifactType(ArtifactTypeEnum.ExtendedArtifactType, null);
        at.setExtendedType(extendedType);
        at.setExtendedDerivedType(derived);
        return at;
    }

    public static final ArtifactType ExtendedDocument(String extendedType) {
        ArtifactType at = new ArtifactType(ArtifactTypeEnum.ExtendedDocument, null);
        at.setExtendedType(extendedType);
        return at;
    }

    private ArtifactTypeEnum artifactType;
    private String mimeType;
    /** for a Extended Type, the type should be stored here */
    private String extendedType;
    private boolean extendedDerivedType;

    /**
     * Constructor.
     * @param artifactType
     * @param mimeType
     */
    private ArtifactType(ArtifactTypeEnum artifactType, String mimeType) {
        setArtifactType(artifactType);
        // TODO: This needs re-thought.  The mimeType should only be non-null when artifactType.isDocument().  But
        // if you let null happen, you'll eventually get NPEs within RESTEasy.
        if (mimeType == null) {
            if (artifactType == ArtifactTypeEnum.Document || artifactType == ArtifactTypeEnum.ExtendedDocument) {
                mimeType = "application/octet-stream";
            } else {
                mimeType = "application/xml";
            }
        }
        setMimeType(mimeType);
    }

    /**
     * Called to unwrap the S-RAMP artifact from its wrapper.
     * @param artifactWrapper the S-RAMP artifact wrapper
     * @return the specific artifact based on type
     */
    public BaseArtifactType unwrap(Artifact artifactWrapper) {
        try {
            Method method = Artifact.class.getMethod("get" + getArtifactType().getType());
            BaseArtifactType artifact = (BaseArtifactType) method.invoke(artifactWrapper);
            artifact.setArtifactType(this.getArtifactType().getApiType());
            return artifact;
        } catch (Exception e) {
            throw new RuntimeException(Messages.i18n.format("ARTIFACT_UNWRAP_ERROR", getArtifactType().getType()),
                    e);
        }
    }

    /**
     * Figures out the artifact type (enum) from the given S-RAMP artifact type string.
     * @param artifactType
     */
    public static ArtifactType valueOf(String artifactType) {
        return valueOf(artifactType, false);
    }

    public static ArtifactType valueOf(String artifactType, boolean isDocument) {
        if (StringUtils.isEmpty(artifactType)) {
            return null;
        } else if (ArtifactTypeEnum.hasEnum(artifactType)) {
            ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.valueOf(artifactType);
            return new ArtifactType(artifactTypeEnum, null);
        } else {
            ArtifactTypeEnum artifactTypeEnum;
            if (isDocument) {
                artifactTypeEnum = ArtifactTypeEnum.ExtendedDocument;
            } else {
                artifactTypeEnum = ArtifactTypeEnum.ExtendedArtifactType;
            }
            ArtifactType rval = new ArtifactType(artifactTypeEnum, null);
            rval.setExtendedType(artifactType);
            rval.setMimeType("application/octet-stream");
            return rval;
        }
    }

    /**
     * Determines the ArtifactType from the model and type. If the model is "ext"
     * (extended) then the artifactType can be either ExtendedArtifactType or
     * ExtendedDocument. All extended artifacts that have contend inherit from
     * ExtendedDocument. 
     * 
     * @param model - the model, for example core, xsd, wsdl, ext, etc.
     * @param type - the type, for example XmlDocument, WsdlDocument
     * @param isDocument - this flag is taken into account ONLY when the model is 'ext',
     * in this case the 'type' can be ExtendedDocument,
     * ExtendedArtifactType, or a user defined value (for example 'SwitchYardApplication').
     * The flag 'isDocument' is required only if the type is user defined so it can 
     * distinguish between an artifact with (true) or without (false) content. 
     * If this is not known at the time of calling a value of null can be given which will 
     * default the ArtifactType of ExtendedArtifactType.
     * 
     * @return ArtifactType
     */
    public static ArtifactType valueOf(String model, String type, Boolean isDocument) {
        ArtifactType artifactType = null;
        if ("ext".equals(model)) {
            ArtifactTypeEnum artifactTypeEnum = null;
            if (type.equals(ArtifactTypeEnum.ExtendedDocument.getType())
                    || (!type.equals(ArtifactTypeEnum.ExtendedArtifactType.getType()) && isDocument != null
                            && isDocument)) {
                artifactTypeEnum = ArtifactTypeEnum.ExtendedDocument;
            } else {
                artifactTypeEnum = ArtifactTypeEnum.ExtendedArtifactType;
            }
            artifactType = new ArtifactType(artifactTypeEnum, null);
            artifactType.setExtendedType(type);
        } else {
            ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.valueOf(type);
            artifactType = new ArtifactType(artifactTypeEnum, null);
        }
        return artifactType;
    }

    /**
     * Figures out the type from the artifact instance.
     * @param artifact
     */
    public static ArtifactType valueOf(BaseArtifactType artifact) {
        BaseArtifactEnum apiType = artifact.getArtifactType();
        // First, figure it out by the ArtifactType enum on the object
        if (apiType != null) {
            ArtifactType artifactType = valueOf(apiType);
            if (DocumentArtifactType.class.isAssignableFrom(artifact.getClass())) {
                artifactType.setMimeType(((DocumentArtifactType) artifact).getContentType());
            }
            if (artifactType.isExtendedType()) {
                if ((artifact.getOtherAttributes().keySet()
                        .contains(ArtificerConstants.SRAMP_CONTENT_TYPE_QNAME))) {
                    String contentTypeStr = artifact.getOtherAttributes()
                            .get(ArtificerConstants.SRAMP_CONTENT_TYPE_QNAME);
                    artifactType.setMimeType(contentTypeStr);
                }
                String extendedDerived = artifact.getOtherAttributes().get(ArtificerConstants.SRAMP_DERIVED_QNAME);
                artifactType.setExtendedDerivedType("true".equals(extendedDerived));
            }
            if (artifactType.getArtifactType() == ArtifactTypeEnum.ExtendedArtifactType) {
                String extendedType = ((ExtendedArtifactType) artifact).getExtendedType();
                artifactType.setExtendedType(extendedType);
            } else if (artifactType.getArtifactType() == ArtifactTypeEnum.ExtendedDocument) {
                String extendedType = ((ExtendedDocument) artifact).getExtendedType();
                artifactType.setExtendedType(extendedType);
            }
            return artifactType;
        }
        // If that didn't work, then iterate through and test against all possible artifact types.
        ArtifactTypeEnum[] values = ArtifactTypeEnum.values();
        for (ArtifactTypeEnum artifactTypeEnum : values) {
            if (artifactTypeEnum.getTypeClass().equals(artifact.getClass())) {
                ArtifactType artifactType = new ArtifactType(artifactTypeEnum, null);
                if (artifactTypeEnum == ArtifactTypeEnum.ExtendedArtifactType
                        || artifactTypeEnum == ArtifactTypeEnum.ExtendedDocument) {
                    if ((artifact.getOtherAttributes().keySet()
                            .contains(ArtificerConstants.SRAMP_CONTENT_TYPE_QNAME))) {
                        String contentTypeStr = artifact.getOtherAttributes()
                                .get(ArtificerConstants.SRAMP_CONTENT_TYPE_QNAME);
                        artifactType.setMimeType(contentTypeStr);
                    }
                    String extendedType = (artifact instanceof ExtendedArtifactType)
                            ? ((ExtendedArtifactType) artifact).getExtendedType()
                            : ((ExtendedDocument) artifact).getExtendedType();
                    String extendedDerived = artifact.getOtherAttributes()
                            .get(ArtificerConstants.SRAMP_DERIVED_QNAME);
                    artifactType.setExtendedType(extendedType);
                    artifactType.setExtendedDerivedType("true".equals(extendedDerived));
                }
                return artifactType;
            }
        }
        throw new RuntimeException(Messages.i18n.format("ARTIFACT_TYPE_FROM_CLASS_ERROR", artifact.getClass()));
    }

    /**
     * Instantiates an S-RAMP artifact of the correct type, and populates the artifactType and the
     * contentType.
     * @param artifactType
     */
    public BaseArtifactType newArtifactInstance() {
        try {
            BaseArtifactType baseArtifactType = getArtifactType().getTypeClass().newInstance();
            baseArtifactType.setArtifactType(getArtifactType().getApiType());
            if (DocumentArtifactType.class.isAssignableFrom(baseArtifactType.getClass())) {
                ((DocumentArtifactType) baseArtifactType).setContentType(getMimeType());
            }
            if (getArtifactType() == ArtifactTypeEnum.ExtendedArtifactType) {
                baseArtifactType.getOtherAttributes().put(ArtificerConstants.SRAMP_CONTENT_TYPE_QNAME,
                        getMimeType());
                ((ExtendedArtifactType) baseArtifactType).setExtendedType(getExtendedType());
            }
            if (getArtifactType() == ArtifactTypeEnum.ExtendedDocument) {
                baseArtifactType.getOtherAttributes().put(ArtificerConstants.SRAMP_CONTENT_TYPE_QNAME,
                        getMimeType());
                ((ExtendedDocument) baseArtifactType).setExtendedType(getExtendedType());
            }
            return baseArtifactType;
        } catch (Exception e) {
            throw new RuntimeException(
                    Messages.i18n.format("ARTIFACT_INSTANTIATION_ERROR", getArtifactType().getTypeClass()), e);
        }
    }

    /**
     * Figures out the type from the s-ramp API type.
     * @param apiType
     */
    public static ArtifactType valueOf(BaseArtifactEnum apiType) {
        ArtifactTypeEnum[] values = ArtifactTypeEnum.values();
        for (ArtifactTypeEnum artifactType : values) {
            if (artifactType.getApiType() == apiType) {
                return new ArtifactType(artifactType, null);
            }
        }
        throw new RuntimeException(Messages.i18n.format("ARTIFACT_TYPE_FROM_APITYPE_ERROR", apiType.value()));
    }

    /**
     * @return the artifactType
     */
    public ArtifactTypeEnum getArtifactType() {
        return artifactType;
    }

    /**
     * @return true if the type is a {@link ExtendedArtifactType}.
     */
    public boolean isExtendedType() {
        return getArtifactType() == ArtifactTypeEnum.ExtendedArtifactType
                || getArtifactType() == ArtifactTypeEnum.ExtendedDocument;
    }

    /**
     * @return true if the artifact is a document artifact
     */
    public boolean isDocument() {
        if (isDerived()) {
            return false;
        } else {
            return getArtifactType().isDocument();
        }
    }

    /**
     * @return true if the artifact is derived
     */
    public boolean isDerived() {
        return getArtifactType().isDerived() || isExtendedDerivedType();
    }

    /**
     * @param artifactType the artifactType to set
     */
    public void setArtifactType(ArtifactTypeEnum artifactType) {
        this.artifactType = artifactType;
    }

    /**
     * @return the artifact model
     */
    public String getModel() {
        return getArtifactType().getModel();
    }

    /**
     * @return the artifact type
     */
    public String getType() {
        if (getArtifactType() == ArtifactTypeEnum.ExtendedArtifactType
                || getArtifactType() == ArtifactTypeEnum.ExtendedDocument) {
            return getExtendedType();
        } else {
            return getArtifactType().getType();
        }
    }

    /**
     * @return the artifact type label
     */
    public String getLabel() {
        return getArtifactType().getLabel();
    }

    /**
     * @return the mimeType
     */
    public String getMimeType() {
        return mimeType;
    }

    /**
     * @param mimeType the mimeType to set
     */
    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format("/s-ramp/%1$s/%2$s (%3$s)", getArtifactType().getModel(), getArtifactType().getType(),
                getMimeType());
    }

    /**
     * Sets the extended type.
     * @param extendedType
     */
    public void setExtendedType(String extendedType) {
        if (extendedType != null && !isValid(extendedType)) {
            throw new RuntimeException(Messages.i18n.format("ArtifactType.InvalidExtendedType", extendedType));
        }
        this.extendedType = extendedType;
    }

    /**
     * Gets the extended artifact type.
     */
    public String getExtendedType() {
        return extendedType;
    }

    private static class ModelMime {
        public ModelMime(String extendedModel, String mimeType) {
            this.extendedModel = extendedModel;
            this.mimeType = mimeType;
        }

        public String extendedModel;
        public String mimeType;
    }

    /**
     * What kind of artifact is inside that wrapper?
     * @param artifactWrapper
     */
    public static ArtifactType valueOf(Artifact artifactWrapper, String hint) {
        ArtifactType type = null;
        // We were given a hint - try using that first.
        if (hint != null) {
            String methodName = "get" + hint;
            try {
                Method method = artifactWrapper.getClass().getMethod(methodName);
                Object o = method.invoke(artifactWrapper);
                if (o != null && BaseArtifactType.class.isAssignableFrom(o.getClass())) {
                    Class<? extends BaseArtifactType> artyClass = ((BaseArtifactType) o).getClass();
                    return valueOf(artyClass);
                }
            } catch (Exception e) {
                // eat it
            }
        }

        // Didn't find it based on the hint - try them all!
        if (type == null) {
            Method[] methods = artifactWrapper.getClass().getMethods();
            try {
                for (Method method : methods) {
                    if (method.getName().startsWith("get")) {
                        Object o = method.invoke(artifactWrapper);
                        if (o != null && BaseArtifactType.class.isAssignableFrom(o.getClass())) {
                            Class<? extends BaseArtifactType> artyClass = ((BaseArtifactType) o).getClass();
                            return valueOf(artyClass);
                        }
                    }
                }
            } catch (Exception e) {
                // eat it
            }
        }
        return type;
    }

    /**
     * Figures out the artifact type from the class.
     * @param artyClass
     */
    private static ArtifactType valueOf(Class<? extends BaseArtifactType> artyClass) {
        ArtifactType rval = null;
        for (ArtifactTypeEnum e : ArtifactTypeEnum.values()) {
            if (e.getTypeClass().equals(artyClass)) {
                rval = new ArtifactType(e, null);
            }
        }
        return rval;
    }

    /**
     * @return the extendedDerivedType
     */
    protected boolean isExtendedDerivedType() {
        return extendedDerivedType;
    }

    /**
     * @param extendedDerivedType the extendedDerivedType to set
     */
    public void setExtendedDerivedType(boolean extendedDerivedType) {
        this.extendedDerivedType = extendedDerivedType;
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((artifactType == null) ? 0 : artifactType.hashCode());
        result = prime * result + ((extendedType == null) ? 0 : extendedType.hashCode());
        return result;
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ArtifactType other = (ArtifactType) obj;
        if (artifactType != other.artifactType)
            return false;
        if (extendedType == null) {
            if (other.extendedType != null)
                return false;
        } else if (!extendedType.equals(other.extendedType))
            return false;
        return true;
    }
}