1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
56 /**
57 * Command definitions file.
58 */
59 public static final String COMMANDS_FILE = "/WEB-INF/commands.xml";
60
61
62 /**
63 * Command definitions file path.
64 */
65 private String commandsFile;
66
67
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 }