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(0, 1).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 }
|