/* * Copyright 2009 Fedora Commons, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mulgara.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URI; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; /** * Provides access to the global ServerInfo class when it is not available as a dependency. * * @created June 08, 2009 * @author Paula Gearon * @copyright © 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a> */ public class ServerInfoRef { /** Logger. */ private static final Logger logger = Logger.getLogger(ServerInfoRef.class.getName()); /** Singleton of the ServerInfo class. */ private static Class<?> si = null; /** Singleton getters, stored by name. */ private static Map<String,Method> getters = new HashMap<String,Method>(); /** Singleton setters, stored by name. */ private static Map<String,Method> setters = new HashMap<String,Method>(); /** * Sets the hostnames on the ServerInfo object, if it is visible. * * @param names The set of hostnames to set on ServerInfo */ public static void setHostnameAliases(Set<String> names) { setServerInfoProperty("HostnameAliases", names); } /** * Method to ask the ServerInfo for the local server aliases. * This will return an empty set if ServerInfo is not available - * ie. being run on a host which has no local database, such an an iTQL client. * * @return The set of server aliases as strings */ @SuppressWarnings("unchecked") public static Set<String> getHostnameAliases() { Set<String> names = (Set<String>)getServerInfoProperty("HostnameAliases"); return (names == null) ? (Set<String>)java.util.Collections.EMPTY_SET : names; } /** * Gets the hostnames on the ServerInfo object, if it is visible. * * @return The default graph URI, used by SPARQL */ public static URI getDefaultURI() { URI u = (URI)getServerInfoProperty("DefaultGraphURI"); if (u == null) { String c = getMulgaraConstant("DEFAULT_GRAPH"); u = (c != null) ? URI.create(c) : URI.create("sys:default"); } return u; } /** * Method to ask the ServerInfo for the local server URI. * This will return null if ServerInfo is not available - * ie. being run on a host which has no local database, such an an iTQL client. * * @return The server URI */ public static URI getServerURI() { return (URI)getServerInfoProperty("ServerURI"); } /** * Get the ServerInfo class as a singleton. * @return The instance of the ServerInfo Class object. * @throws ClassNotFoundException If ServerInfo is not on the classpath. */ private static final Class<?> getServerInfoClass() throws ClassNotFoundException { if (si == null) { si = Class.forName("org.mulgara.server.ServerInfo"); } return si; } /** * Sets a property on the ServerInfo, if it is available * @param name The name of the property. Case sensitive. * @param value The value of the property to be set. */ public static final void setServerInfoProperty(String name, Object value) { try { Method setter = findSetter(name, value); if (setter != null) { setter.invoke(null, new Object[] { value }); } else { logger.info("No setter method found in Server Info for: " + name); } } catch (Exception e) { /* Not much that can be done here */ logger.info("Unable to set '" + name + "' for Server Info", e); } } /** * Gets a property from the ServerInfo, if it is available * @param name The name of the property. Case sensitive. * @return The value, or <code>null</code> if not available. */ public static final Object getServerInfoProperty(String name) { try { Method getter = findGetter(name); return getter.invoke(null, new Object[] { }); } catch (Exception e) { /* Not much that can be done here */ logger.debug("Unable to get '" + name + "' from Server Info", e); return null; } } /** * Get the Getter for a property as a singleton to be stored by name. * @param name The name of the property to find the getter for. * @return The method used for getting the property. * @throws SecurityException If the method is not allowed to be used. * @throws NoSuchMethodException If the readable property does not exist. * @throws ClassNotFoundException If the ServerInfo class is not on the classpath. */ private static final Method findGetter(String name) throws SecurityException, NoSuchMethodException, ClassNotFoundException { String fullName = "get" + name; Method getter = getters.get(fullName); if (getter == null) { getter = getServerInfoClass().getMethod(fullName, new Class[] { }); getters.put(fullName, getter); } return getter; } /** * Get the Setter for a property as a singleton to be stored by name. * @param name The name of the property to find the setter for. * @param value The value of the property to be set. * @return The method used for setting the property. * @throws SecurityException If the method is not allowed to be used. * @throws ClassNotFoundException If the ServerInfo class is not on the classpath. */ private static final Method findSetter(String name, Object value) throws SecurityException, ClassNotFoundException { String fullName = "set" + name; Method setter = setters.get(fullName); if (setter == null) { for (Class<?>cls: getSuperTypes(value.getClass())) { try { setter = getServerInfoClass().getMethod(fullName, new Class[] { cls }); break; } catch (NoSuchMethodException e) { /* continue */ } } setters.put(fullName, setter); } return setter; } /** * Get the list of all superclasses and interfaces that a class meets. * @param cls The class to get all supertypes of. * @return A List of classes and interfaces that this class extends. */ private static final List<Class<?>> getSuperTypes(Class<?> cls) { List<Class<?>> result = new LinkedList<Class<?>>(); for (Class<?> i: cls.getInterfaces()) result.add(i); do { result.add(cls); } while ((cls = cls.getSuperclass()) != null); return result; } /** * Gets a string constant from the Mulgara class. * @param name The name of the constant. * @return The string value of the constant, or null if this cannot be retrieved. */ private static final String getMulgaraConstant(String name) { // reflect the data out of the Mulgara class String c = null; try { Class<?> mulgara = Class.forName("org.mulgara.query.rdf.Mulgara"); Field field = mulgara.getDeclaredField(name); c = (String)field.get(null); } catch (Exception e) { logger.error("Unable to find Mulgara constants.", e); } return c; } }