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

src.main.java.com.eva.properties.ProtocolFactory Maven / Gradle / Ivy

Go to download

Advanced properties with object factories, references and inheritance.

There is a newer version: 0.3
Show newest version
/*
 * $Id: ProtocolFactory.java 37 2007-02-27 11:42:55Z max $
 * 
 * Copyright (c) 2006-2007 Maximilian Antoni. All rights reserved.
 * 
 * This software is licensed as described in the file LICENSE.txt, which you
 * should have received as part of this distribution. The terms are also
 * available at http://www.maxantoni.de/projects/eva-properties/license.txt.
 */
package com.eva.properties;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * creates objects for protocol-style strings.
 * 
 * @author Max Antoni
 * @version $Revision: 37 $
 */
abstract class ProtocolFactory {
    /**
     * protocol name for classpath URLs.
     */
    private static final String PROTOCOL_CLASSPATH = "classpath";
    /**
     * protocol name for {@link DataSource datasources}.
     */
    private static final String PROTOCOL_DATASOURCE = "datasource";
    /**
     * protocol name for files.
     */
    private static final String PROTOCOL_FILE = "file";
    /**
     * protocol name for URLs.
     */
    private static final String PROTOCOL_URL = "url";
    /**
     * protocol name for Java classes.
     */
    private static final String PROTOCOL_CLASS = "class";
    /**
     * protocol name for static instances.
     */
    private static final String PROTOCOL_STATIC = "static";
    /**
     * protocol name for strings that start with a protocol.
     */
    private static final String PROTOCOL_STRING = "string";
    private static final String COLON_SLASH_SLASH = "://";
    private static final Map PROTOCOL_FACTORIES;
    private static final Pattern PROTOCOL_PATTERN = Pattern.compile(
            "^([a-z]{3,})\\:\\/\\/.*");
    
    static {
        PROTOCOL_FACTORIES = new HashMap();
        PROTOCOL_FACTORIES.put(PROTOCOL_STRING, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath) {
                return removePrefix(inPath);
            }
        });
        PROTOCOL_FACTORIES.put(PROTOCOL_CLASS, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath) {
                return inContext.loadClass(removePrefix(inPath));
            }
        });
        PROTOCOL_FACTORIES.put(PROTOCOL_STATIC, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath) {
                String path = removePrefix(inPath);
                int p = path.indexOf('#');
                if(p == -1) {
                    throw new IllegalArgumentException("No hash found in "
                            + inPath);
                }
                Class clazz = inContext.loadClass(path.substring(0, p));
                String instance = path.substring(p + 1);
                Field field;
                try {
                    field = clazz.getField(instance);
                }
                catch(SecurityException e) {
                    throw new RuntimeException(e);
                }
                catch(NoSuchFieldException e) {
                    throw new RuntimeException(e);
                }
                if(Modifier.isStatic(field.getModifiers())) {
                    try {
                        return field.get(null);
                    }
                    catch(IllegalArgumentException e) {
                        throw new RuntimeException(e);
                    }
                    catch(IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
                throw new IllegalArgumentException(clazz.getName() + "#"
                        + instance + " is not static.");
            }
        });
        PROTOCOL_FACTORIES.put(PROTOCOL_URL, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath)
                    throws FileNotFoundException {
                try {
                    return new URL(removePrefix(inPath));
                }
                catch(MalformedURLException e) {
                    throw new FileNotFoundException(e.getMessage());
                }
            }
        });
        PROTOCOL_FACTORIES.put(PROTOCOL_FILE, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath) {
                return new File(removePrefix(inPath).replace('/',
                        File.separatorChar));
            }
        });
        PROTOCOL_FACTORIES.put(PROTOCOL_DATASOURCE, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath)
                    throws FileNotFoundException, PropertiesException {
                return new DataSource((ClassLoader) inContext
                        .lookup("classloader"), removePrefix(inPath));
            }
        });
        PROTOCOL_FACTORIES.put(PROTOCOL_CLASSPATH, new ProtocolFactory() {
            /*
             * @see com.eva.properties.ProtocolFactory#build(
             *      com.eva.properties.Context, java.lang.String)
             */
            Object build(Context inContext, String inPath)
                    throws FileNotFoundException, PropertiesException {
                return new DataSource((ClassLoader) inContext
                        .lookup("classloader"), inPath);
            }
        });
    }
    
    /**
     * 

* returns an object for a string. If the string starts with a protocol, the * replacement for that specific protocol will be returned. If the protocol * references any kind of file, but the file is not found, null * is returned. If an exception is catched during the creation of the * object, it will be wrapped in a {@link PropertiesException}. *

*

* If the given string does not match a protocol, the sting itself is * returned. *

* * @param inContext the context. * @param inString the string to be replaced. * @return the replaced object, the string argument or null. * @throws PropertiesException if an exception was thrown while creating the * object. */ static Object forString(Context inContext, String inString) throws PropertiesException { Matcher matcher = PROTOCOL_PATTERN.matcher(inString); if(matcher.matches()) { ProtocolFactory factory = (ProtocolFactory) PROTOCOL_FACTORIES.get( matcher.group(1)); if(factory == null) { try { return new URL(inString); } catch(MalformedURLException e) { throw new PropertiesException(e); } } try { return factory.build(inContext, inString); } catch(FileNotFoundException e) { if(Log.INSTANCE.isLoggable(Level.FINE)) { Log.INSTANCE.fine("Properties: File not found, " + e.getMessage()); } return null; // Try next if in switch } } return inString; // not a URL } /** * standard constructor. */ ProtocolFactory() { super(); } /** * creates an object for a path. * * @param inContext the context. * @param inPath the path. * @return the object. * @throws FileNotFoundException if the object is a file that cannot be * found. * @throws PropertiesException if any unexpected exception accours that * cannot be handled properly by throwing a * FileNotFoundException. */ abstract Object build(Context inContext, String inPath) throws FileNotFoundException, PropertiesException; /** * helper method that removes the protocol prefix from a url. * * @param inUrl the url. * @return the url without the prefix. */ String removePrefix(String inUrl) { return inUrl.substring(inUrl.indexOf(COLON_SLASH_SLASH) + COLON_SLASH_SLASH.length()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy