//# 0 errors, 68 messages
//#
/*
    //#actionfactory.java:1:1: class: net.sourceforge.pebble.web.action.ActionFactory
 * Copyright (c) 2003-2006, Simon Brown
 * All 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 Pebble 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 net.sourceforge.pebble.web.action;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * A factory class from which to look up and retrieve an instance
 * of an Action class to process a specific request.
 *
 * @author    Simon Brown
 */
public class ActionFactory {

  /** the log used by this class */
  private static Log log = LogFactory.getLog(ActionFactory.class);
    //#actionfactory.java:52: method: net.sourceforge.pebble.web.action.ActionFactory.net.sourceforge.pebble.web.action.ActionFactory__static_init
    //#actionfactory.java:52: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.web.action.ActionFactory
    //#    method: net.sourceforge.pebble.web.action.ActionFactory__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(net.sourceforge.pebble.web.action.ActionFactory__static_init): __Descendant_Table[net/sourceforge/pebble/web/action/ActionFactory]
    //#output(net.sourceforge.pebble.web.action.ActionFactory__static_init): __Dispatch_Table.getAction(Ljava/lang/String;)Lnet/sourceforge/pebble/web/action/Action;
    //#output(net.sourceforge.pebble.web.action.ActionFactory__static_init): __Dispatch_Table.init()V
    //#output(net.sourceforge.pebble.web.action.ActionFactory__static_init): log
    //#post(net.sourceforge.pebble.web.action.ActionFactory__static_init): __Descendant_Table[net/sourceforge/pebble/web/action/ActionFactory] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.web.action.ActionFactory__static_init): __Dispatch_Table.getAction(Ljava/lang/String;)Lnet/sourceforge/pebble/web/action/Action; == &getAction
    //#post(net.sourceforge.pebble.web.action.ActionFactory__static_init): __Dispatch_Table.init()V == &init
    //#post(net.sourceforge.pebble.web.action.ActionFactory__static_init): init'ed(log)
    //#actionfactory.java:52: end of method: net.sourceforge.pebble.web.action.ActionFactory.net.sourceforge.pebble.web.action.ActionFactory__static_init

  /** the collection of actions that we know about */
  private Map actions = new HashMap();

  /** the name of the action mapping file */
  private String actionMappingFileName;

  /**
   * Creates a new instance, using the given configuration file.
   */
  public ActionFactory(String actionMappingFileName) {
    //#actionfactory.java:63: method: void net.sourceforge.pebble.web.action.ActionFactory.net.sourceforge.pebble.web.action.ActionFactory(String)
    //#input(void net.sourceforge.pebble.web.action.ActionFactory(String)): actionMappingFileName
    //#input(void net.sourceforge.pebble.web.action.ActionFactory(String)): log
    //#input(void net.sourceforge.pebble.web.action.ActionFactory(String)): this
    //#output(void net.sourceforge.pebble.web.action.ActionFactory(String)): new HashMap(ActionFactory#1) num objects
    //#output(void net.sourceforge.pebble.web.action.ActionFactory(String)): this.actionMappingFileName
    //#output(void net.sourceforge.pebble.web.action.ActionFactory(String)): this.actions
    //#new obj(void net.sourceforge.pebble.web.action.ActionFactory(String)): new HashMap(ActionFactory#1)
    //#pre[2] (void net.sourceforge.pebble.web.action.ActionFactory(String)): (soft) log != null
    //#post(void net.sourceforge.pebble.web.action.ActionFactory(String)): this.actionMappingFileName == actionMappingFileName
    //#post(void net.sourceforge.pebble.web.action.ActionFactory(String)): init'ed(this.actionMappingFileName)
    //#post(void net.sourceforge.pebble.web.action.ActionFactory(String)): this.actions == &new HashMap(ActionFactory#1)
    //#post(void net.sourceforge.pebble.web.action.ActionFactory(String)): new HashMap(ActionFactory#1) num objects == 1
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.lang.Object:getClass
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.lang.Class:getClassLoader
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.lang.ClassLoader:getResourceAsStream
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Properties
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Properties:load
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Properties:propertyNames
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Properties:getProperty
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.util.Map:put
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.lang.Exception:getMessage
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:org.apache.commons.logging.Log:error
    //#unanalyzed(void net.sourceforge.pebble.web.action.ActionFactory(String)): Effects-of-calling:java.lang.Exception:printStackTrace
    this.actionMappingFileName = actionMappingFileName;
    init();
  }
    //#actionfactory.java:66: end of method: void net.sourceforge.pebble.web.action.ActionFactory.net.sourceforge.pebble.web.action.ActionFactory(String)

  /**
   * Initialises this component, reading in and creating the map
   * of action names to action classes.
   */
  private void init() {
    try {
      // load the properties file containing the name -> class name mapping
      InputStream in = getClass().getClassLoader().getResourceAsStream(actionMappingFileName);
    //#actionfactory.java:75: method: void net.sourceforge.pebble.web.action.ActionFactory.init()
    //#input(void init()): log
    //#input(void init()): this
    //#input(void init()): this.actionMappingFileName
    //#input(void init()): this.actions
    //#pre[1] (void init()): (soft) log != null
    //#pre[3] (void init()): (soft) init'ed(this.actionMappingFileName)
    //#pre[4] (void init()): (soft) this.actions != null
    //#presumption(void init()): java.lang.Class:getClassLoader(...)@75 != null
    //#presumption(void init()): java.lang.Object:getClass(...)@75 != null
    //#presumption(void init()): java.util.Properties:propertyNames(...)@80 != null
      Properties props = new Properties();
      props.load(in);

      // and store them in a HashMap
      Enumeration e = props.propertyNames();
      String actionName;
      String className;

      while (e.hasMoreElements()) {
        actionName = (String)e.nextElement();
        className = props.getProperty(actionName);

        actions.put(actionName, className);
      }

    } catch (Exception e) {
      log.error(e.getMessage(), e);
    //#actionfactory.java:92: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object, Throwable)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.web.action.ActionFactory
    //#    method: void init()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object, Throwable)
      e.printStackTrace();
    }
  }
    //#actionfactory.java:95: end of method: void net.sourceforge.pebble.web.action.ActionFactory.init()

  /**
   * Given the name/type of request, this method returns the Action
   * instance appropriate to process the request.
   *
   * @param name    the name (type) of the request
   * @return  an instance of Action (could be null if no mapping has been defined)
   */
  public Action getAction(String name) throws ActionNotFoundException {
    try {
      // instantiate the appropriate class to handle the request
      if (actions.containsKey(name)) {
    //#actionfactory.java:107: method: Action net.sourceforge.pebble.web.action.ActionFactory.getAction(String)
    //#input(Action getAction(String)): name
    //#input(Action getAction(String)): net/sourceforge/pebble/web/action/Action.__Descendant_Table[others]
    //#input(Action getAction(String)): this
    //#input(Action getAction(String)): this.actions
    //#output(Action getAction(String)): return_value
    //#pre[4] (Action getAction(String)): this.actions != null
    //#presumption(Action getAction(String)): java.lang.Class:getClassLoader(...)@108 != null
    //#presumption(Action getAction(String)): java.lang.Class:newInstance(...).__Tag@109 is init'ed
    //#presumption(Action getAction(String)): java.lang.ClassLoader:loadClass(...)@108 != null
    //#presumption(Action getAction(String)): java.lang.Object:getClass(...)@108 != null
    //#presumption(Action getAction(String)): java.util.Map:containsKey(...)@107 == 1
    //#post(Action getAction(String)): return_value != null
    //#unanalyzed(Action getAction(String)): Effects-of-calling:java.lang.Exception
        Class c = getClass().getClassLoader().loadClass((String)actions.get(name));
        Action action = (Action)c.newInstance();

        return action;
      } else {
        throw new ActionNotFoundException("An action called " + name + " could not be found");
      }
    } catch (ClassNotFoundException cnfe) {
      log.error(cnfe.getMessage(), cnfe);
      throw new ActionNotFoundException("An action called " + name + " could not be loaded : " + cnfe.getMessage());
    } catch (IllegalAccessException iae) {
      log.error(iae.getMessage(), iae);
      throw new ActionNotFoundException("An action called " + name + " could not be created : " + iae.getMessage());
    } catch (InstantiationException ie) {
      log.error(ie.getMessage(), ie);
      throw new ActionNotFoundException("An action called " + name + " could not be created : " + ie.getMessage());
    //#actionfactory.java:123: end of method: Action net.sourceforge.pebble.web.action.ActionFactory.getAction(String)
    }
  }

}    //#actionfactory.java:: end of class: net.sourceforge.pebble.web.action.ActionFactory
