View Javadoc

1   /*
2    * This file is part of Pease Plate Template Engine.
3    * 
4    * Pease Plate Template Engine is free software: you can redistribute
5    * it and/or modify it under the terms of the GNU Lesser General 
6    * Public License as published by the Free Software Foundation, 
7    * either version 3 of the License, or any later version.
8    * 
9    * Pease Plate Template Engine is distributed in the hope that it 
10   * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11   * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12   * See the GNU Lesser General Public License for more details.
13   * 
14   * You should have received a copy of the GNU Lesser General Public 
15   * License along with Pease Plate Template Engine. If not, see 
16   * <http://www.gnu.org/licenses/>.
17   * 
18   * Copyright (c) 2008 Manfred HANTSCHEL
19   */
20  package org.peaseplate.internal.util;
21  
22  import java.io.BufferedReader;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.InputStreamReader;
26  import java.net.URL;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.Enumeration;
31  
32  public class ServiceConfiguration {
33  
34  	private final Class<?> serviceClass;
35  	private final ClassLoader[] classLoaders;
36  	private final Collection<Class<?>> contributions;
37  
38  	public ServiceConfiguration(Class<?> serviceClass, Collection<ClassLoader> classLoaders) throws IOException {
39  		this(serviceClass, classLoaders.toArray(new ClassLoader[classLoaders.size()]));
40  	}
41  
42  	public ServiceConfiguration(Class<?> serviceClass, ClassLoader... classLoaders) throws IOException {
43  		super();
44  		
45  		this.serviceClass = serviceClass;
46  		this.classLoaders = classLoaders;
47  		
48  		contributions = new ArrayList<Class<?>>();
49  		
50  		load();
51  	}
52  	
53  	public Collection<Class<?>> getContributions() {
54  		return Collections.unmodifiableCollection(contributions);
55  	}
56  	
57  	public boolean containsContribution(Class<?> contribution) {
58  		return contributions.contains(contribution);
59  	}
60  	
61  	protected void load() throws IOException {
62  		for (ClassLoader classLoader : classLoaders) {
63              Enumeration<URL> en = classLoader.getResources(
64              	"META-INF/services/" + serviceClass.getName()
65              );
66              
67              while (en.hasMoreElements()) {
68              	URL url = en.nextElement();
69              	InputStream in = url.openStream();
70              	
71              	try {
72              		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
73              		
74              		try {
75              			String line = null;
76              			
77              			while ((line = reader.readLine()) != null) {
78              				if (!line.startsWith("#")) {
79              					line = line.trim();
80              					
81              					if (line.length() > 0)
82              						contributions.add(resolveClass(url, line));
83              				}
84              			}
85              		}
86              		finally {
87              			reader.close();
88              		}
89              	}
90              	finally {
91              		in.close();
92              	}
93              }
94  		}
95  	}
96  
97  	protected Class<?> resolveClass(URL resource, String classname) throws IOException {
98  		Class<?> result = null;
99  		
100 		for (int i=classLoaders.length-1; i>=0; i-=1) {
101 			try {
102 	            result = classLoaders[i].loadClass(classname);
103             }
104             catch (ClassNotFoundException e) {
105             	// ignore
106             }
107 		}
108 		
109 		if (result == null)
110         	throw new IOException(
111         		"Could not find class " + classname + " as referenced in service configuration " + resource
112         	);
113 		
114 		return result;
115     }
116 
117 	/**
118      * @see java.lang.Object#toString()
119      */
120     @Override
121     public String toString() {
122     	StringBuilder builder = new StringBuilder(getClass().getName());
123     	
124     	builder.append(" [\n");
125     	
126     	for (Class<?> contribution : contributions)
127     		builder.append("\t").append(contribution).append("\n");
128     	
129     	builder.append("]");
130     	
131     	return builder.toString();
132     }
133 }