001: /**
002: * Copyright 2004, Gareth Cronin
003: * User: garethc
004: * Date: 6/06/2004
005: * Time: 09:19:14
006: */package vqwiki;
007:
008: import org.apache.log4j.Logger;
009:
010: import java.io.File;
011: import java.io.FileOutputStream;
012: import java.io.IOException;
013: import java.io.InputStream;
014: import java.net.URL;
015: import java.util.Properties;
016:
017: /**
018: * Manager that maintains bindings between logical action names and classes that implement {@link WikiAction}
019: * The action manager can delegate requests to appropriate actions.
020: */
021: public class ActionManager {
022:
023: /** Logger */
024: public static final Logger logger = Logger
025: .getLogger(ActionManager.class);
026: /** Mapping of action names to classes */
027: private Properties mapping;
028: /** Singleton instance */
029: private static ActionManager ourInstance = new ActionManager();
030: /** Name of the resource that is the mapping file to persist to */
031: private static final String MAPPING_PROPERTIES_FILE = "/actions.properties";
032:
033: /**
034: * Get singleton instance
035: *
036: * @return singleton instance
037: */
038: public static ActionManager getInstance() {
039: return ourInstance;
040: }
041:
042: /**
043: * Hide constructor
044: */
045: private ActionManager() {
046: }
047:
048: /**
049: * Return an instance of the named action
050: *
051: * @param actionName name
052: * @return instance or null if there is no mapping for the named action
053: * @throws ClassNotFoundException if the mapped class can't be found
054: * @throws IllegalAccessException on a security problem
055: * @throws InstantiationException if the mapped class can't be instantiated
056: */
057: public WikiAction getActionInstance(String actionName)
058: throws ClassNotFoundException, IllegalAccessException,
059: InstantiationException {
060: logger.debug("getting action instance: " + actionName);
061: String className = getMapping().getProperty(actionName);
062: if (className == null) {
063: return null;
064: }
065: Class clazz = Class.forName(className);
066: return (WikiAction) clazz.newInstance();
067: }
068:
069: /**
070: * Get the current mapping
071: *
072: * @return mapping
073: */
074: private Properties getMapping() {
075: if (mapping == null) {
076: InputStream in = ActionManager.class
077: .getResourceAsStream(MAPPING_PROPERTIES_FILE);
078: if (in == null) {
079: logger.warn(MAPPING_PROPERTIES_FILE + " not found");
080: }
081: mapping = new Properties();
082: try {
083: mapping.load(in);
084: in.close();
085: } catch (IOException e) {
086: logger.warn(e);
087: }
088: }
089: logger.debug("mapping: " + mapping);
090: return mapping;
091: }
092:
093: /**
094: * Add a mapping
095: *
096: * @param actionName action name
097: * @param className class implementing {@link WikiAction}
098: * @throws IOException on any error persisting the mapping
099: */
100: public void addMapping(String actionName, String className)
101: throws IOException {
102: logger.debug("adding action mapping: " + actionName + "->"
103: + className);
104: getMapping().setProperty(actionName, className);
105: URL base = ActionManager.class.getResource("/");
106: FileOutputStream out = null;
107: try {
108: out = new FileOutputStream(new File(base.getFile(),
109: MAPPING_PROPERTIES_FILE));
110: getMapping().store(out, "actions");
111: } finally {
112: if (out != null) {
113: out.close();
114: }
115: }
116: }
117:
118: /**
119: * Return whether a mapping exists for the named action
120: *
121: * @param actionName action name
122: * @return true if it exists
123: */
124: public boolean actionExists(String actionName) {
125: boolean result = getMapping().containsKey(actionName);
126: logger.debug("action exists: '" + actionName + "' ?" + result);
127: return result;
128: }
129: }
|