| 
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 import griffon.core.injection.Binding;
 023 import org.codehaus.griffon.runtime.core.injection.Bindings;
 024 import org.codehaus.griffon.runtime.core.injection.LinkedBindingBuilder;
 025
 026 import javax.annotation.Nonnull;
 027 import javax.annotation.Nullable;
 028 import javax.inject.Inject;
 029 import java.util.ArrayList;
 030 import java.util.Collection;
 031 import java.util.Collections;
 032 import java.util.List;
 033 import java.util.Map;
 034 import java.util.TreeMap;
 035
 036 import static griffon.util.AnnotationUtils.typed;
 037 import static griffon.util.GriffonNameUtils.requireNonBlank;
 038 import static java.util.Objects.requireNonNull;
 039
 040 /**
 041  * Base implementation of the ArtifactHandler interface.
 042  *
 043  * @author Andres Almiray
 044  * @since 2.0.0
 045  */
 046 public abstract class AbstractArtifactHandler<A extends GriffonArtifact> implements ArtifactHandler<A> {
 047     protected static final String ERROR_CLASS_NULL = "Argument 'class' must not be null";
 048     private final Class<A> artifactType;
 049     private final String type;
 050     private final String trailing;
 051     private final GriffonApplication application;
 052
 053     private GriffonClass[] griffonClasses = new GriffonClass[0];
 054     private final Map<String, GriffonClass> classesByName = new TreeMap<>();
 055
 056     @Inject
 057     public AbstractArtifactHandler(@Nonnull GriffonApplication application, @Nonnull Class<A> artifactType, @Nonnull String type, @Nonnull String trailing) {
 058         this.application = requireNonNull(application, "Argument 'application' must not be null");
 059         this.artifactType = requireNonNull(artifactType, "Argument 'artifactType' must not be null");
 060         this.type = requireNonBlank(type, "Argument 'type' must not be blank");
 061         this.trailing = requireNonNull(trailing, "Argument 'trailing' must not be null");
 062     }
 063
 064     @Nonnull
 065     public Class<A> getArtifactType() {
 066         return artifactType;
 067     }
 068
 069     @Nonnull
 070     public String getType() {
 071         return type;
 072     }
 073
 074     @Nonnull
 075     public String getTrailing() {
 076         return trailing;
 077     }
 078
 079     @Nonnull
 080     public Collection<Binding<?>> initialize(@Nonnull Class<A>[] classes) {
 081         griffonClasses = new GriffonClass[classes.length];
 082         List<Binding<?>> bindings = new ArrayList<>();
 083         for (int i = 0; i < classes.length; i++) {
 084             Class<A> klass = classes[i];
 085             GriffonClass griffonClass = newGriffonClassInstance(klass);
 086             griffonClasses[i] = griffonClass;
 087             classesByName.put(klass.getName(), griffonClass);
 088             createBindings(bindings, klass, griffonClass);
 089         }
 090         return bindings;
 091     }
 092
 093     protected void createBindings(@Nonnull List<Binding<?>> bindings, @Nonnull Class<A> clazz, @Nonnull GriffonClass griffonClass) {
 094         LinkedBindingBuilder<GriffonClass> builder = Bindings.bind(GriffonClass.class)
 095             .withClassifier(typed(clazz));
 096         builder.toInstance(griffonClass);
 097         bindings.add(builder.getBinding());
 098         bindings.add(Bindings.bind(clazz).getBinding());
 099     }
 100
 101     @Nonnull
 102     public Map<String, GriffonClass> getClassesByName() {
 103         return Collections.unmodifiableMap(classesByName);
 104     }
 105
 106     /**
 107      * Returns true if the target Class is a class artifact
 108      * handled by this object.<p>
 109      * This implementation performs an equality check on class.name
 110      */
 111     public boolean isArtifact(@Nonnull Class<A> clazz) {
 112         requireNonNull(clazz, ERROR_CLASS_NULL);
 113         return classesByName.get(clazz.getName()) != null;
 114     }
 115
 116     public boolean isArtifact(@Nonnull GriffonClass clazz) {
 117         requireNonNull(clazz, ERROR_CLASS_NULL);
 118         for (GriffonClass griffonClass : griffonClasses) {
 119             if (griffonClass.equals(clazz)) return true;
 120         }
 121         return false;
 122     }
 123
 124     @Nonnull
 125     public GriffonClass[] getClasses() {
 126         return griffonClasses;
 127     }
 128
 129     @Nullable
 130     public GriffonClass getClassFor(@Nonnull Class<A> clazz) {
 131         requireNonNull(clazz, ERROR_CLASS_NULL);
 132         return getClassFor(clazz.getName());
 133     }
 134
 135     @Nullable
 136     public GriffonClass getClassFor(@Nonnull String fqnClassName) {
 137         requireNonBlank(fqnClassName, "Argument 'fqnClassName' must not be blank");
 138         return classesByName.get(fqnClassName);
 139     }
 140
 141     @Nullable
 142     public GriffonClass findClassFor(@Nonnull String propertyName) {
 143         requireNonBlank(propertyName, "Argument 'propertyName' must not be blank");
 144
 145         String simpleName = propertyName;
 146
 147         int lastDot = propertyName.lastIndexOf(".");
 148         if (lastDot > -1) {
 149             simpleName = simpleName.substring(lastDot + 1);
 150         }
 151
 152         if (simpleName.length() == 1) {
 153             simpleName = simpleName.toUpperCase();
 154         } else {
 155             simpleName = simpleName.substring(0, 1).toUpperCase() + simpleName.substring(1);
 156         }
 157
 158         if (!simpleName.endsWith(trailing)) {
 159             simpleName += trailing;
 160         }
 161
 162         for (GriffonClass griffonClass : griffonClasses) {
 163             if (griffonClass.getClazz().getSimpleName().equals(simpleName)) {
 164                 return griffonClass;
 165             }
 166         }
 167
 168         return null;
 169     }
 170
 171     @Nonnull
 172     protected GriffonApplication getApplication() {
 173         return application;
 174     }
 175 }
 |