001 /*
002 * Copyright 2008-2015 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(0, 1).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 }
|