AbstractArtifactHandler.java
001 /*
002  * Copyright 2008-2016 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package org.codehaus.griffon.runtime.core.artifact;
017 
018 import griffon.core.GriffonApplication;
019 import griffon.core.artifact.ArtifactHandler;
020 import griffon.core.artifact.GriffonArtifact;
021 import griffon.core.artifact.GriffonClass;
022 
023 import javax.annotation.Nonnull;
024 import javax.annotation.Nullable;
025 import javax.inject.Inject;
026 import java.util.Collections;
027 import java.util.Map;
028 import java.util.TreeMap;
029 
030 import static griffon.util.GriffonNameUtils.requireNonBlank;
031 import static java.util.Objects.requireNonNull;
032 
033 /**
034  * Base implementation of the ArtifactHandler interface.
035  *
036  @author Andres Almiray
037  @since 2.0.0
038  */
039 public abstract class AbstractArtifactHandler<A extends GriffonArtifact> implements ArtifactHandler<A> {
040     protected static final String ERROR_CLASS_NULL = "Argument 'class' must not be null";
041     private final Class<A> artifactType;
042     private final String type;
043     private final String trailing;
044     private final GriffonApplication application;
045     private final Map<String, GriffonClass> classesByName = new TreeMap<>();
046     private GriffonClass[] griffonClasses = new GriffonClass[0];
047 
048     @Inject
049     public AbstractArtifactHandler(@Nonnull GriffonApplication application, @Nonnull Class<A> artifactType, @Nonnull String type, @Nonnull String trailing) {
050         this.application = requireNonNull(application, "Argument 'application' must not be null");
051         this.artifactType = requireNonNull(artifactType, "Argument 'artifactType' must not be null");
052         this.type = requireNonBlank(type, "Argument 'type' must not be blank");
053         this.trailing = requireNonNull(trailing, "Argument 'trailing' must not be null");
054     }
055 
056     @Nonnull
057     public Class<A> getArtifactType() {
058         return artifactType;
059     }
060 
061     @Nonnull
062     public String getType() {
063         return type;
064     }
065 
066     @Nonnull
067     public String getTrailing() {
068         return trailing;
069     }
070 
071     public void initialize(@Nonnull Class<A>[] classes) {
072         griffonClasses = new GriffonClass[classes.length];
073         for (int i = 0; i < classes.length; i++) {
074             Class<A> klass = classes[i];
075             GriffonClass griffonClass = newGriffonClassInstance(klass);
076             griffonClasses[i= griffonClass;
077             classesByName.put(klass.getName(), griffonClass);
078         }
079     }
080 
081     @Nonnull
082     public Map<String, GriffonClass> getClassesByName() {
083         return Collections.unmodifiableMap(classesByName);
084     }
085 
086     /**
087      * Returns true if the target Class is a class artifact
088      * handled by this object.<p>
089      * This implementation performs an equality check on class.name
090      */
091     public boolean isArtifact(@Nonnull Class<A> clazz) {
092         requireNonNull(clazz, ERROR_CLASS_NULL);
093         return classesByName.get(clazz.getName()) != null;
094     }
095 
096     public boolean isArtifact(@Nonnull GriffonClass clazz) {
097         requireNonNull(clazz, ERROR_CLASS_NULL);
098         for (GriffonClass griffonClass : griffonClasses) {
099             if (griffonClass.equals(clazz)) return true;
100         }
101         return false;
102     }
103 
104     @Nonnull
105     public GriffonClass[] getClasses() {
106         return griffonClasses;
107     }
108 
109     @Nullable
110     public GriffonClass getClassFor(@Nonnull Class<A> clazz) {
111         requireNonNull(clazz, ERROR_CLASS_NULL);
112         return getClassFor(clazz.getName());
113     }
114 
115     @Nullable
116     public GriffonClass getClassFor(@Nonnull String fqnClassName) {
117         requireNonBlank(fqnClassName, "Argument 'fqnClassName' must not be blank");
118         return classesByName.get(fqnClassName);
119     }
120 
121     @Nullable
122     public GriffonClass findClassFor(@Nonnull String propertyName) {
123         requireNonBlank(propertyName, "Argument 'propertyName' must not be blank");
124 
125         String simpleName = propertyName;
126 
127         int lastDot = propertyName.lastIndexOf(".");
128         if (lastDot > -1) {
129             simpleName = simpleName.substring(lastDot + 1);
130         }
131 
132         if (simpleName.length() == 1) {
133             simpleName = simpleName.toUpperCase();
134         else {
135             simpleName = simpleName.substring(01).toUpperCase() + simpleName.substring(1);
136         }
137 
138         if (!simpleName.endsWith(trailing)) {
139             simpleName += trailing;
140         }
141 
142         for (GriffonClass griffonClass : griffonClasses) {
143             if (griffonClass.getClazz().getSimpleName().equals(simpleName)) {
144                 return griffonClass;
145             }
146         }
147 
148         return null;
149     }
150 
151     @Nonnull
152     protected GriffonApplication getApplication() {
153         return application;
154     }
155 }