All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrdf.repository.object.managers.helpers.RoleClassLoader Maven / Gradle / Ivy

Go to download

The Object Composition library merges multiple Java objects into a single multi-subject object.

The newest version!
/*
 * Copyright (c) 2009, James Leigh All rights reserved.
 * Copyright (c) 2011 Talis Inc., Some rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution. 
 * - Neither the name of the openrdf.org nor the names of its contributors may
 *   be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 */
package org.openrdf.repository.object.managers.helpers;

import org.openrdf.annotations.Iri;
import org.openrdf.annotations.Matching;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.repository.object.exceptions.ObjectStoreConfigException;
import org.openrdf.repository.object.managers.RoleMapper;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.*;

/**
 * Loads the annotations, concepts and behaviours into memory.
 * 
 * @author James Leigh
 * 
 */
public class RoleClassLoader {
	private static final String CONCEPTS = "META-INF/org.openrdf.concepts";
	private static final String BEHAVIOURS = "META-INF/org.openrdf.behaviours";
	private static final String ANNOTATIONS = "META-INF/org.openrdf.annotations";

	private final Logger logger = LoggerFactory.getLogger(DirectMapper.class);

	private RoleMapper roleMapper;

	public RoleClassLoader(RoleMapper roleMapper) {
		this.roleMapper = roleMapper;
	}

	/**
	 * Loads and registers roles listed in resource.
	 * 
	 * @throws ObjectStoreConfigException
	 */
	public void loadRoles(ClassLoader cl) throws ObjectStoreConfigException {
		try {
			ClassLoader first = RoleClassLoader.class.getClassLoader();
			Set loaded;
			loaded = load(new CheckForAnnotation(first), first, "annotations", ANNOTATIONS, true, new HashSet());
			loaded = load(new CheckForAnnotation(cl), cl, "annotations", ANNOTATIONS, true, loaded);
			loaded = load(new CheckForConcept(first), first, "concepts", CONCEPTS, true, new HashSet());
            loaded = load(new CheckForConcept(cl), cl, "concepts", CONCEPTS, true, loaded);
			loaded = load(new CheckForBehaviour(first), first, "behaviours", BEHAVIOURS, false, new HashSet());
			loaded = load(new CheckForBehaviour(cl), cl, "behaviours", BEHAVIOURS, false, loaded);

            scanConceptsWithReflections();

            Collection> concepts = roleMapper.getConceptClasses();
            for(Class conceptClass : concepts) {
                logger.debug("Registered concept class " + conceptClass.getCanonicalName());
            }

		} catch (ObjectStoreConfigException e) {
			throw e;
		} catch (Exception e) {
			throw new ObjectStoreConfigException(e);
		}
	}

	public void scan(URL jar, ClassLoader cl) throws ObjectStoreConfigException {
		scan(jar, new CheckForAnnotation(cl), ANNOTATIONS, cl);
		scan(jar, new CheckForConcept(cl), CONCEPTS, cl);
		scan(jar, new CheckForBehaviour(cl), BEHAVIOURS, cl);
	}

	private void scan(URL url, CheckForConcept checker, String role, ClassLoader cl)
			throws ObjectStoreConfigException {
		try {
			Scanner scanner = new Scanner(checker);
			load(scanner.scan(url, checker.getName(), role), cl, false);
		} catch (Exception e) {
			throw new ObjectStoreConfigException(e);
		}
	}

    private void scanConceptsWithReflections() throws ObjectStoreConfigException {
        logger.debug("Search for concepts with reflections");
        Set classpath = new HashSet<>();
        classpath.addAll(ClasspathHelper.forClassLoader());
        classpath.addAll(ClasspathHelper.forJavaClassPath());
        classpath.addAll(ClasspathHelper.forManifest());
        classpath.addAll(ClasspathHelper.forPackage(""));
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(classpath)
				.useParallelExecutor()
				.filterInputsBy(FilterBuilder.parsePackages("-java, -javax, -sun, -com.sun"))
                .setScanners(new SubTypesScanner(), new TypeAnnotationsScanner()));

        Set> annotated = reflections.getTypesAnnotatedWith(Iri.class, true);
        logger.debug("Search for concepts with reflections resulted in " + annotated.size() + " classes");
        for (Class clazz : annotated) {
            logger.debug("Found concept class: " + clazz.getCanonicalName());
            roleMapper.addConcept(clazz);
        }
    }

	private Set load(CheckForConcept checker, ClassLoader cl, String forType, String roles, boolean concept, Set exclude)
			throws IOException, ClassNotFoundException, ObjectStoreConfigException {
		if (cl == null)
			return exclude;
		Scanner scanner = new Scanner(checker, roles);
		Enumeration resources = cl.getResources(roles);
        while (resources.hasMoreElements()) {
			URL url = resources.nextElement();
			if (!exclude.contains(url)) {
				exclude.add(url);
				logger.debug("Reading roles from {}", url);
				try {
					Properties p = new Properties();
					p.load(url.openStream());


					if (p.isEmpty()) {
                        // exclude concept scanning because of external reflection scanning
                        if(!CONCEPTS.equals(roles)) {
                            load(scanner.scan(url, forType, null), cl, concept);
                        }
					} else {
						load(p, cl, concept);
					}
				} catch (IOException e) {
					String msg = e.getMessage() + " in: " + url;
					throw new ObjectStoreConfigException(msg, e);
				} catch (IllegalArgumentException e) {
					String msg = e.getMessage() + " in: " + url;
					throw new ObjectStoreConfigException(msg, e);
				}
			}
		}
		return exclude;
	}

	private void load(List roles, ClassLoader cl, boolean concept)
			throws IOException, ObjectStoreConfigException {
		for (String role : roles) {
			try {
				Class clazz = forName(role, true, cl);
				recordRole(clazz, null, concept);
			} catch (ClassNotFoundException exc) {
				logger.error(exc.toString());
			}
		}
	}

	private void load(Properties p, ClassLoader cl, boolean concept)
			throws ClassNotFoundException, IOException, ObjectStoreConfigException {
		for (Map.Entry e : p.entrySet()) {
			String role = (String) e.getKey();
			String types = (String) e.getValue();
			try {
				int idx = role.indexOf('#');
				if (idx >= 0) {
					role = role.substring(0, idx);
				}
				Class clazz = forName(role, true, cl);
				for (String rdf : types.split("\\s+")) {
					if (idx < 0) {
						recordRole(clazz, rdf, concept);
					} else {
						String mname = ((String)e.getKey()).substring(idx + 1);
						if (mname.endsWith("()")) {
							mname = mname.substring(0, mname.length() - 2);
						}
						if (rdf.length() > 0) {
							roleMapper.addAnnotation(clazz.getMethod(mname), new URIImpl(rdf));
						} else {
							roleMapper.addAnnotation(clazz.getMethod(mname));
						}
					}
				}
			} catch (ClassNotFoundException exc) {
				logger.error(exc.toString());
			} catch (NoSuchMethodException exc) {
				logger.error(exc.toString());
			}
		}
	}

	private Class forName(String name, boolean init, ClassLoader cl)
			throws ClassNotFoundException {
		synchronized (cl) {
			return Class.forName(name, init, cl);
		}
	}

	private void recordRole(Class clazz, String uri, boolean concept)
			throws ObjectStoreConfigException {
		if (uri == null || uri.length() == 0) {
			if (clazz.isAnnotation()) {
				roleMapper.addAnnotation(clazz);
			} else if (isAnnotationPresent(clazz) || concept) {
				roleMapper.addConcept(clazz);
			} else {
				roleMapper.addBehaviour(clazz);
			}
		} else {
			if (clazz.isAnnotation()) {
				roleMapper.addAnnotation(clazz, new URIImpl(uri));
			} else if (isAnnotationPresent(clazz) || concept) {
				roleMapper.addConcept(clazz, new URIImpl(uri));
			} else {
				roleMapper.addBehaviour(clazz, new URIImpl(uri));
			}
		}
	}

	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;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy