/*******************************************************************************
* Copyright (c) 2009, 2010 Fraunhofer IWU and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Fraunhofer IWU - initial API and implementation
*******************************************************************************/
package net.enilink.komma.em.util;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import net.enilink.composition.annotations.Matching;
import net.enilink.composition.annotations.Iri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.enilink.commons.iterator.IExtendedIterator;
import net.enilink.commons.iterator.WrappedIterator;
import net.enilink.komma.core.KommaException;
import net.enilink.komma.core.KommaModule;
public class RoleClassLoader {
private static final String ANNOTATIONS = "META-INF/org.openrdf.annotations";
private static final String BEHAVIOURS = "META-INF/org.openrdf.behaviours";
private static final String CONCEPTS = "META-INF/org.openrdf.concepts";
private final Logger logger = LoggerFactory
.getLogger(RoleClassLoader.class);
private KommaModule module;
public RoleClassLoader(KommaModule module) {
this.module = module;
}
private boolean isAnnotationPresent(Class<?> clazz) {
for (Annotation ann : clazz.getAnnotations()) {
String name = ann.annotationType().getName();
if (Iri.class.getName().equals(name)) {
return true;
}
if (Matching.class.getName().equals(name)) {
return true;
}
}
return false;
}
public void load() {
Set<URL> seenUrls = new HashSet<URL>();
for (String roles : Arrays.asList(CONCEPTS, BEHAVIOURS, ANNOTATIONS)) {
try {
IExtendedIterator<URL> resources = WrappedIterator
.create(module.getClassLoader().getResources(roles));
load(resources, seenUrls);
} catch (Exception e) {
throw new KommaException(e);
}
}
}
private void load(Iterator<URL> resources, Set<URL> exclude)
throws IOException, ClassNotFoundException {
while (resources.hasNext()) {
URL url = resources.next();
if (!exclude.contains(url)) {
exclude.add(url);
logger.info("Reading roles from {}", url);
try {
Properties p = new Properties();
p.load(url.openStream());
load(p);
} catch (IOException e) {
String msg = e.getMessage() + " in: " + url;
IOException ioe = new IOException(msg);
ioe.initCause(e);
throw ioe;
}
}
}
}
private void load(Properties p) throws IOException {
for (Map.Entry<Object, Object> e : p.entrySet()) {
String role = (String) e.getKey();
String types = (String) e.getValue();
try {
Class<?> clazz = Class.forName(role, true,
module.getClassLoader());
for (String rdf : types.split("\\s+")) {
recordRole(clazz, rdf);
}
} catch (Throwable exc) {
logger.error("Could not load " + role, exc);
}
}
}
private void recordRole(Class<?> clazz, String uri) {
boolean uriMapped = uri != null && uri.length() > 0;
if (!uriMapped || isAnnotationPresent(clazz)) {
if (clazz.isAnnotation()) {
module.addAnnotation(clazz);
} else if (clazz.isInterface()) {
module.addConcept(clazz);
} else {
module.addBehaviour(clazz);
}
}
if (uriMapped) {
if (clazz.isAnnotation()) {
module.addAnnotation(clazz, uri);
} else if (clazz.isInterface()) {
module.addConcept(clazz, uri);
} else {
module.addBehaviour(clazz, uri);
}
}
}
}