001 /*
002 * Copyright 2009-2013 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
017 package org.codehaus.griffon.runtime.core;
018
019 import griffon.core.ArtifactInfo;
020 import griffon.core.GriffonApplication;
021 import griffon.util.ApplicationClassLoader;
022 import groovy.util.ConfigObject;
023 import groovy.util.ConfigSlurper;
024 import org.slf4j.Logger;
025 import org.slf4j.LoggerFactory;
026
027 import java.io.IOException;
028 import java.lang.reflect.Modifier;
029 import java.net.URL;
030 import java.util.*;
031
032 import static org.codehaus.griffon.runtime.util.GriffonApplicationHelper.loadClass;
033
034 /**
035 * Default implementation of {@code ArtifactManager}.
036 *
037 * @author Andres Almiray
038 * @since 0.9.2
039 */
040 public class DefaultArtifactManager extends AbstractArtifactManager {
041 private static final Logger LOG = LoggerFactory.getLogger(DefaultArtifactManager.class);
042
043 public DefaultArtifactManager(GriffonApplication app) {
044 super(app);
045 }
046
047 protected Map<String, List<ArtifactInfo>> doLoadArtifactMetadata() {
048 Map<String, List<ArtifactInfo>> artifacts = new LinkedHashMap<String, List<ArtifactInfo>>();
049 try {
050 Enumeration<URL> urls = getArtifactResourceLocations();
051 ConfigSlurper slurper = new ConfigSlurper();
052 while (urls.hasMoreElements()) {
053 processURL(urls.nextElement(), slurper, artifacts);
054 }
055 } catch (IOException e) {
056 throw new IllegalArgumentException(e);
057 }
058
059 return artifacts;
060 }
061
062 protected Enumeration<URL> getArtifactResourceLocations() throws IOException {
063 return ApplicationClassLoader.get().getResources("META-INF/griffon-artifacts.properties");
064 }
065
066 private void processURL(URL url, ConfigSlurper slurper, Map<String, List<ArtifactInfo>> artifacts) {
067 Properties p = new Properties();
068 try {
069 p.load(url.openStream());
070 } catch (IOException e) {
071 return;
072 }
073
074 ConfigObject config = slurper.parse(p);
075 if (LOG.isDebugEnabled()) {
076 LOG.debug("Loading artifact definitions from " + url);
077 }
078
079 for (Object key : config.keySet()) {
080 String type = key.toString();
081 String classes = (String) config.get(type);
082 if (classes.startsWith("'") && classes.endsWith("'")) {
083 classes = classes.substring(1, classes.length() - 1);
084 }
085 String[] classNames = classes.split(",");
086 if (LOG.isDebugEnabled()) {
087 LOG.debug("Artifacts of type '" + type + "' = " + classNames.length);
088 }
089
090 List<ArtifactInfo> list = artifacts.get(type);
091 if (list == null) {
092 list = new ArrayList<ArtifactInfo>();
093 artifacts.put(type, list);
094 }
095
096 for (String className : classNames) {
097 try {
098 Class clazz = loadClass(className);
099 if (Modifier.isAbstract(clazz.getModifiers())) continue;
100 ArtifactInfo info = new ArtifactInfo(clazz, type);
101 if (!list.contains(info)) list.add(info);
102 } catch (ClassNotFoundException e) {
103 throw new IllegalArgumentException(e);
104 }
105 }
106 }
107 }
108 }
|