View Javadoc

1   /*
2    * Copyright 2004-2006 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.tuigwaa.cms.core.wiki.base;
17  
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.Iterator;
21  import java.util.List;
22  
23  import org.apache.commons.configuration.Configuration;
24  import org.apache.commons.configuration.ConfigurationException;
25  import org.apache.commons.configuration.ConfigurationFactory;
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.seasar.tuigwaa.cms.core.CmsEngine;
29  import org.seasar.tuigwaa.cms.core.wiki.WikiContext;
30  import org.seasar.tuigwaa.plugin.AbstractPlugin;
31  import org.seasar.tuigwaa.plugin.Plugin;
32  import org.seasar.tuigwaa.plugin.PluginConfig;
33  
34  /***
35   * Loads wiki engine configuration and creates WikiConfiguration object
36   * 
37   * @author someda
38   */
39  public class WikiConfigurationFactory {
40  
41  	private static final String PATH = "/commons-configuration.xml";
42  
43  	private static final String XML_ELEMENT_DEBUG = "debug";
44  
45  	private static final String XML_ELEMENT_CONTEXT = "context";
46  
47  	private static final String XML_ELEMENT_ENGINE = "engine";
48  
49  	private static final String XML_ATTRIBUTE_ENGINE_CONTENTTYPE = "contentType";
50  
51  	private static final String XML_ATTRIBUTE_ENGINE_CLASS = "class";
52  
53  	private static final String XML_ELEMENT_PLUGIN = "plugin";
54  
55  	private static final String XML_ATTRIBUTE_PLUGIN_NAME = "name";
56  
57  	private static final String XML_ATTRIBUTE_PLUGIN_CLASS = "class";
58  
59  	private static final String XML_ATTRIBUTE_PLUGIN_TYPE = "type";
60  
61  	private static final String XML_VALUE_PLUGIN_TYPE_BLOCK = "block";
62  
63  	private static final String XML_VALUE_PLUGIN_TYPE_INLINE = "inline";
64  
65  	private static final String XML_VALUE_PLUGIN_TYPE_BOTH = "both";
66  
67  	private static final String XML_ELEMENT_SUPPORT = "support";
68  
69  	private static final String XML_ATTRIBUTE_SUPPORT_HTML = "html";
70  
71  	private static final String XML_ATTRIBUTE_SUPPORT_PDF = "pdf";
72  
73  	private static Log log_ = LogFactory.getLog(WikiConfigurationFactory.class);
74  
75  	private static WikiConfigurationFactory instance_;
76  
77  	private static WikiConfiguration wikiconfig_;
78  
79  	private WikiConfigurationFactory() {
80  	}
81  
82  	public static synchronized WikiConfigurationFactory getInstance() {
83  		if (instance_ == null) {
84  			instance_ = new WikiConfigurationFactory();
85  		}
86  		return instance_;
87  	}
88  
89  	public WikiConfiguration createConfiguration() throws WikiException {
90  
91  		if (wikiconfig_ == null) {
92  			wikiconfig_ = new WikiConfiguration();
93  			load(wikiconfig_);
94  		}
95  		return wikiconfig_;
96  	}
97  
98  	private void load(WikiConfiguration wikiconfig) throws WikiException {
99  		try {
100 			ConfigurationFactory factory = new ConfigurationFactory();
101 			factory.setConfigurationURL(getClass().getResource(PATH));
102 			Configuration config = factory.getConfiguration();
103 
104 			loadDebug(config, wikiconfig);
105 			// mandatory settings
106 			loadContext(config, wikiconfig);
107 			loadEngine(config, wikiconfig);
108 			loadPlugin(config, wikiconfig);
109 
110 		} catch (ConfigurationException ce) {
111 			log_.fatal("Loading configuration file " + PATH + " failed.");
112 		}
113 	}
114 
115 	private void loadDebug(Configuration config, WikiConfiguration wikiconfig) {
116 		if (config.containsKey(XML_ELEMENT_DEBUG))
117 			wikiconfig.setDebug(config.getBoolean(XML_ELEMENT_DEBUG));
118 	}
119 
120 	private void loadContext(Configuration config, WikiConfiguration wikiconfig)
121 			throws WikiException {
122 		if (config.containsKey(XML_ELEMENT_CONTEXT)) {
123 			String contextClass = config.getString(XML_ELEMENT_CONTEXT);
124 			try {
125 				WikiContext context = (WikiContext) Class.forName(contextClass)
126 						.newInstance();
127 				wikiconfig.setWikiContext(context);
128 			} catch (ClassCastException cce) {
129 				log_.error(contextClass
130 						+ " must implement com.isenshi.wiki.WikiContext.");
131 				cce.printStackTrace();
132 			} catch (InstantiationException ie) {
133 				log_.error(contextClass + " instantiation failed.");
134 				ie.printStackTrace();
135 			} catch (IllegalAccessException iae) {
136 				log_.error(contextClass + " is not allowed to access.");
137 				iae.printStackTrace();
138 			} catch (ClassNotFoundException cnfe) {
139 				log_.error(contextClass + " is not found.");
140 				cnfe.printStackTrace();
141 			}
142 		} else {
143 			throw new WikiException("context is not be found.");
144 		}
145 	}
146 
147 	private void loadEngine(Configuration config, WikiConfiguration wikiconfig)
148 			throws WikiException {
149 
150 		if (config.containsKey(getKey(XML_ELEMENT_ENGINE, -1,
151 				XML_ATTRIBUTE_ENGINE_CONTENTTYPE))) {
152 			List contentTypeList = new ArrayList();
153 
154 			Object pluginobj = config.getProperty(getKey(XML_ELEMENT_ENGINE,
155 					-1, XML_ATTRIBUTE_ENGINE_CONTENTTYPE));
156 			if (pluginobj instanceof Collection) {
157 				for (Iterator itr = ((Collection) pluginobj).iterator(); itr
158 						.hasNext();) {
159 					String name = (String) itr.next();
160 					contentTypeList.add(name);
161 				}
162 			} else {
163 				contentTypeList.add((String) pluginobj);
164 			}
165 
166 			for (int i = 0; i < contentTypeList.size(); i++) {
167 				String contentType = (String) contentTypeList.get(i);
168 
169 				String classkey = getKey(XML_ELEMENT_ENGINE, i,
170 						XML_ATTRIBUTE_ENGINE_CLASS);
171 				if (!config.containsKey(classkey)) {
172 					log_.error("attribute \'class\' must be specified.");
173 					log_.error(contentType
174 							+ " contentType is not be configured.");
175 					continue;
176 				}
177 				String classname = config.getString(classkey);
178 				CmsEngine engine;
179 				try {
180 					engine = (CmsEngine) Class.forName(classname).newInstance();
181 					wikiconfig.addEngine(contentType, engine);
182 					engine.setConfiguration(wikiconfig);
183 					log_.info(classname + " engine loaded.");
184 				} catch (InstantiationException ie) {
185 					log_.error(classname + " instantiation failed.");
186 					ie.printStackTrace();
187 				} catch (IllegalAccessException iae) {
188 					log_.error(classname + " is not allowed to access.");
189 					iae.printStackTrace();
190 				} catch (ClassNotFoundException cnfe) {
191 					log_.error(classname + " is not found.");
192 					cnfe.printStackTrace();
193 				}
194 			}
195 		}
196 	}
197 
198 	private void loadPlugin(Configuration config, WikiConfiguration wikiconfig) {
199 
200 		// WikiConfiguration are common for all Plugin
201 		AbstractPlugin.setConfiguration(wikiconfig);
202 
203 		if (config.containsKey(getKey(XML_ELEMENT_PLUGIN, -1,
204 				XML_ATTRIBUTE_PLUGIN_NAME))) {
205 			List namelist = new ArrayList();
206 
207 			Object pluginobj = config.getProperty(getKey(XML_ELEMENT_PLUGIN,
208 					-1, XML_ATTRIBUTE_PLUGIN_NAME));
209 			if (pluginobj instanceof Collection) {
210 				for (Iterator itr = ((Collection) pluginobj).iterator(); itr
211 						.hasNext();) {
212 					String name = (String) itr.next();
213 					namelist.add(name);
214 				}
215 			} else {
216 				namelist.add((String) pluginobj);
217 			}
218 
219 			for (int i = 0; i < namelist.size(); i++) {
220 				String name = (String) namelist.get(i);
221 
222 				String classkey = getKey(XML_ELEMENT_PLUGIN, i,
223 						XML_ATTRIBUTE_PLUGIN_CLASS);
224 				try {
225 					if (!config.containsKey(classkey)) {
226 						log_.error("attribute \'class\' must be specified.");
227 						log_.error(name + " plugin is not be configured.");
228 						continue;
229 					}
230 					String classname = config.getString(classkey);
231 					Plugin plugin;
232 
233 					if ((plugin = wikiconfig.getPluginByClassname(classname)) != null) {
234 						wikiconfig.addPlugin(name, plugin);
235 						log_.info(name + " " + classname
236 								+ " has already been loaded.");
237 					} else {
238 						try {
239 							plugin = (Plugin) Class.forName(classname)
240 									.newInstance();
241 							loadPluginSetting(config, plugin, i);
242 							wikiconfig.addPlugin(name, plugin);
243 							log_.info(name + " plugin loaded.");
244 						} catch (InstantiationException ie) {
245 							log_.error(classname + " instantiation failed.");
246 							ie.printStackTrace();
247 						} catch (IllegalAccessException iae) {
248 							log_
249 									.error(classname
250 											+ " is not allowed to access.");
251 							iae.printStackTrace();
252 						} catch (ClassNotFoundException cnfe) {
253 							log_.error(classname + " is not found.");
254 							cnfe.printStackTrace();
255 						}
256 					}
257 				} catch (Exception e) {
258 					log_.error(" is not loaded.");
259 					e.printStackTrace();
260 				}
261 			}
262 		}
263 	}
264 
265 	private void loadPluginSetting(Configuration config, Plugin plugin, int idx) {
266 		String typekey = getKey(XML_ELEMENT_PLUGIN, idx,
267 				XML_ATTRIBUTE_PLUGIN_TYPE);
268 		PluginConfig pluginConfig = new PluginConfig();
269 		if (config.containsKey(typekey)) {
270 			String type = config.getString(typekey);
271 			if (type.equalsIgnoreCase(XML_VALUE_PLUGIN_TYPE_BLOCK)) {
272 				pluginConfig.setPluginmode(AbstractPlugin.BLOCKPLUGIN_MODE);
273 			} else if (type.equalsIgnoreCase(XML_VALUE_PLUGIN_TYPE_INLINE)) {
274 				pluginConfig.setPluginmode(AbstractPlugin.INLINEPLUGIN_MODE);
275 			} else if (type.equalsIgnoreCase(XML_VALUE_PLUGIN_TYPE_BOTH)) {
276 				pluginConfig
277 						.setPluginmode((short) (AbstractPlugin.INLINEPLUGIN_MODE | AbstractPlugin.BLOCKPLUGIN_MODE));
278 			} else {
279 				log_.error(type + " is ignored.");
280 			}
281 		}
282 
283 		String supportelement = XML_ELEMENT_PLUGIN + "(" + idx + ")."
284 				+ XML_ELEMENT_SUPPORT;
285 
286 		String htmlkey = getKey(supportelement, -1, XML_ATTRIBUTE_SUPPORT_HTML);
287 		if (config.containsKey(htmlkey)) {
288 			pluginConfig.setHtmlSupported(config.getBoolean(htmlkey));
289 		}
290 
291 		String pdfkey = getKey(supportelement, -1, XML_ATTRIBUTE_SUPPORT_PDF);
292 		if (config.containsKey(pdfkey)) {
293 			pluginConfig.setPdfSupported(config.getBoolean(pdfkey));
294 		}
295 		plugin.setPluginConfig(pluginConfig);
296 	}
297 
298 	private String getKey(String element, int idx, String attr) {
299 		StringBuffer buf = new StringBuffer(element);
300 		if (idx >= 0)
301 			buf.append("(" + idx + ")");
302 
303 		if (attr != null)
304 			buf.append("[@" + attr + "]");
305 
306 		return buf.toString();
307 	}
308 
309 }