View Javadoc

1   /*
2    * $Id: XmlCommandsFactory.java 269 2005-08-10 17:49:22Z josem $
3    *
4    * Tarsis
5    * Copyright (C) 2002 Talika Open Source Group
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   *
21   */
22  
23  package org.talika.tarsis.command.factory.xml;
24  
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.util.Map;
28  
29  import javax.xml.parsers.ParserConfigurationException;
30  import javax.xml.parsers.SAXParserFactory;
31  
32  import org.talika.tarsis.command.factory.CommandFactoryService;
33  import org.talika.tarsis.context.Context;
34  import org.talika.tarsis.log.Logger;
35  import org.talika.tarsis.service.ServiceException;
36  import org.xml.sax.InputSource;
37  import org.xml.sax.SAXException;
38  import org.xml.sax.SAXParseException;
39  import org.xml.sax.XMLReader;
40  
41  /**
42   * XML based implementation of <code>CommandFactory</code> interface.<br>
43   * <br>
44   * It reads command definitions from an XML file that defaults to
45   * <code>/WEB-INF/commands.xml</code>.<br>
46   * <br>
47   * Definitions are loaded when factory is initialized.
48   *
49   * @author  Jose M. Palomar
50   * @version $Revision: 269 $
51   * @see XmlCommandFactory
52   */
53  public final class XmlCommandsFactory extends CommandFactoryService {
54  
55      // Constants
56      /**
57       * Command definitions file.
58       */
59      public static final String COMMANDS_FILE = "/WEB-INF/commands.xml";
60  
61      // Fields
62      /**
63       * Command definitions file path.
64       */
65      private String commandsFile;
66  
67      // Constructors
68      /**
69       * Creates a new <code>XmlCommandsFactory</code> object.
70       */
71      public XmlCommandsFactory() {
72      }
73  
74      /**
75       * Called by the framework to indicate that is being placed into service.<br>
76       * <br>
77       * Initialization secuence:
78       * <ol>
79       * <li> Call super <code>init</code> method.</li>
80       * <li> Checks if <code>commandsFile</code> is set if not sets its value to
81       * <code>COMMANDS_FILE</code>.</li>
82       * <li> Obtains <code>Logger</code> instance from context.</li>
83       * <li> Loads commands from <code>commandsFile</code>.</li>
84       * </ol>
85       *
86       * @param context Context context that initialized service.
87       * @throws ServiceException if an exception has occurred that interferes with the
88       * services's normal operation
89       * @see org.talika.tarsis.service.Service#init(Context)
90       */
91      public void init(Context context) throws ServiceException {
92          super.init(context);
93  
94          if (this.commandsFile == null) {
95              this.commandsFile = COMMANDS_FILE;
96          }
97  
98          loadCommands();
99  
100     }
101 
102     /**
103      * Service name.
104      *
105      * @return String service name.
106      * @see org.talika.tarsis.service.Service#getName()
107      */
108     public String getName() {
109         return "XmlCommandsFactory";
110     }
111 
112     /**
113      * Tries to load command definition from repository for a given name.<br>
114      * <br>
115      * This implementation does nothing because commands are loaded at init time.
116      *
117      * @param commandName String name of command to load.
118      */
119     protected void loadCommand(String commandName) {
120     }
121 
122     /**
123      * Tries to load all command definitions from repository for a given package.<br>
124      * This implementation does nothing because commands are loaded at init time.
125      *
126      * @param packageName String name for package to load.
127      */
128     protected void loadPackage(String packageName) {
129     }
130 
131     /**
132      * Load commands from command definitions file.
133      */
134     protected void loadCommands() {
135 
136         if (getLogger().isInfoEnabled()) {
137             getLogger().logInfo("Loading commands from file " + commandsFile);
138         }
139         
140         InputStream input = getContext().getResourceAsStream(commandsFile);
141         if (input != null) {
142             Map commands = loadXmlCommands(new InputSource(input));
143             if (commands != null) {
144                 addCommands(commands);
145             }
146             else {
147                 if (getLogger().isWarningEnabled()) {
148                     getLogger().logWarning("Error loading commands file");
149                 }
150             }
151         }
152         else {
153             if (getLogger().isWarningEnabled()) {
154                 getLogger().logWarning("File not found " + commandsFile);
155             }
156         }
157 
158     }
159 
160     /**
161      * Loads command definitions from an XML source.
162      *
163      * @param input InputSource XML source.
164      * @return Map a map with all package commands or <code>null</code> if something
165      * wrong happens parsing XML source.
166      */
167     protected Map loadXmlCommands(InputSource input) {
168 
169         try {
170 
171             SAXParserFactory spf = SAXParserFactory.newInstance();
172             spf.setValidating(true);
173             spf.setNamespaceAware(false);
174 
175             XMLReader parser = null;
176             parser = spf.newSAXParser().getXMLReader();
177             XmlCommandPackageLoader packageLoader = new XmlCommandPackageLoader(getContext());
178             XmlCommandsHandler handler = new XmlCommandsHandler(packageLoader);
179             parser.setContentHandler(handler);
180             parser.setErrorHandler(handler);
181             parser.setEntityResolver(handler);
182             parser.parse(input);
183 
184             return handler.getCommands();
185 
186         }
187         catch (SAXParseException spe) {
188             if (getLogger().isDebugEnabled()) {
189                 getLogger().logDebug("Error parsing commands (" + spe.getMessage() + ")");
190             }
191         }
192         catch (SAXException se) {
193             if (se.getException() != null) {
194                 if (getLogger().isDebugEnabled()) {
195                     getLogger().logDebug("Error parsing commands (" + se.getException().getMessage() + ")");
196                 }
197             }
198             else {
199                 if (getLogger().isDebugEnabled()) {
200                     getLogger().logDebug("Error parsing commands (" + se.getMessage() + ")");
201                 }
202             }
203         }
204         catch (ParserConfigurationException pce) {
205             if (getLogger().isDebugEnabled()) {
206                 getLogger().logDebug("Error parsing commands (" + pce.getMessage() + ")");
207             }
208         }
209         catch (IOException ioe) {
210             if (getLogger().isDebugEnabled()) {
211                 getLogger().logDebug("Error parsing commands (" + ioe.getMessage() + ")");
212             }
213         }
214 
215         return null;
216 
217     }
218 
219     /**
220      * Returns command definitions file.
221      *
222      * @return String command definitions file.
223      */
224     public String getCommandsFile() {
225         return commandsFile;
226     }
227 
228     /**
229      * Sets command definitions file.
230      *
231      * @param commandsFile String command definitions file.
232      */
233     public void setCommandsFile(String commandsFile) {
234         this.commandsFile = commandsFile;
235     }
236 
237 }