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