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.plugin;
17  
18  import java.io.BufferedReader;
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.InputStreamReader;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.seasar.tuigwaa.cms.core.CmsRequest;
34  import org.seasar.tuigwaa.cms.core.CmsResponse;
35  import org.seasar.tuigwaa.cms.core.pdf.PdfUtils;
36  import org.seasar.tuigwaa.cms.core.wiki.base.VisitorUtils;
37  import org.seasar.tuigwaa.cms.core.wiki.base.WikiConfiguration;
38  import org.seasar.tuigwaa.cms.core.wiki.base.WikiHelper;
39  import org.seasar.tuigwaa.cms.core.wiki.engine.SimpleNode;
40  import org.seasar.tuigwaa.cms.core.wiki.engine.WikiArgs;
41  import org.seasar.tuigwaa.cms.core.wiki.engine.WikiInlinePlugin;
42  import org.seasar.tuigwaa.system.Constants;
43  import org.seasar.tuigwaa.util.TgwContext;
44  
45  import com.isenshi.util.CharUtil;
46  import com.isenshi.util.HtmlBuffer;
47  
48  
49  /***
50   * @author someda
51   */
52  public abstract class AbstractPlugin implements Plugin {
53  	
54  	public static final short BLOCKPLUGIN_MODE = 001;
55  	public static final short INLINEPLUGIN_MODE = 010;		
56  	
57  	private PluginConfig pluginConfig_;
58  	
59  	
60  	private static final String JAVASCRIPT_TEMPLATE_PATH = "org/seasar/tuigwaa/plugin/plugin_js.tmpl.txt";
61  	
62  	private static Pattern JAVASCRIPT_FUNCTION_PATTERN = Pattern.compile("function (.+)//(.*//)");
63  	private static Pattern INLINEPLUGIN_PATTERN = Pattern.compile("&(//w+)(.+)");
64  	
65  	private static Pattern HTML_STANDARDTAG_PATTERN = Pattern.compile("<//w+.+>(.+)<///w+>");
66  	private static Pattern HTML_STANDALONE_PATTERN = Pattern.compile("<//w+.+/>");
67  	
68  	private static Log classlog_ = LogFactory.getLog(AbstractPlugin.class);
69  	
70  	private static WikiConfiguration config_;
71  	
72  	private static Map javascriptTemplateMap_ = loadTemplate();
73  
74  		
75  	public AbstractPlugin(){
76  	}
77  	
78  	
79  				
80  	// ----- [Start] Plugin interface methods -----
81  	public final boolean isBlockpluginSupported() {
82  		return ((pluginConfig_.getPluginmode() & BLOCKPLUGIN_MODE) == BLOCKPLUGIN_MODE);
83  	}
84  
85  	public final boolean isInlinepluginSupported() {
86  		return ((pluginConfig_.getPluginmode() & INLINEPLUGIN_MODE) == INLINEPLUGIN_MODE);
87  	}
88  	
89  	public final boolean isHtmlSupported() {
90  		return pluginConfig_.isHtmlSupported();
91  	}
92  	
93  	public final boolean isPdfSupported() {
94  		return pluginConfig_.isPdfSupported();
95  	}
96  	
97  	public final Object service(CmsRequest request, CmsResponse response, PluginRequest prequest)
98  	throws PluginException{
99  		
100 		validate(request,response,prequest);
101 		
102 		try{
103 			initialize(request,response,prequest);
104 		}catch(PluginException pe){
105 			classlog_.error("initialize failed for " + getClass().getName());
106 			classlog_.error(pe.getMessage());
107 			// should remove plugin configuration ??
108 		}
109 		
110 		// nested inline plugin process
111 		updateArgs(request,response,prequest);		
112 		
113 		Object result = null;
114 		if(request.isHTMLRequest()){
115 			result = doHTMLView(request,response,prequest);
116 		}else if(request.isPDFRequest()){
117 			result = doPDFView(request,response,prequest);
118 		}else if(request.isRTFRequest()){
119 			// need to implement
120 		}else if(request.isTextRequest()){
121 			result = doTextView(request,response,prequest);
122 		}
123 		return result;
124 	}
125 		
126 	public abstract String doHTMLView(CmsRequest request, CmsResponse response, PluginRequest prequest) throws PluginException;
127 	
128 	public Object doPDFView(CmsRequest request, CmsResponse response, PluginRequest prequest) throws PluginException{				
129 		return PdfUtils.convertHTMLtoPDF(doHTMLView(request,response,prequest));
130 	}
131 	
132 	protected String doTextView(CmsRequest request, CmsResponse response, PluginRequest prequest) throws PluginException{
133 		
134 		String html = doHTMLView(request,response,prequest);
135 		html = CharUtil.removeReturnSequence(html);
136 		Matcher m1 = HTML_STANDARDTAG_PATTERN.matcher(html);
137 		Matcher m2 = HTML_STANDALONE_PATTERN.matcher(html);
138 		if(m1.find()){
139 			html = m1.group(1);
140 		}else if(m2.find()){
141 			html = "";
142 		}
143 		return VisitorUtils.unescape(html);
144 	}
145 	
146 	public String doAction(HttpServletRequest request, HttpServletResponse response) {
147 		return null;
148 	}
149 		
150 	public void setPluginConfig(PluginConfig pluginConfig){
151 		this.pluginConfig_ = pluginConfig;
152 	}
153 	
154 	// ----- [End] Plugin interface methods -----			
155 
156 	// ----- [Start] Other public methods -----	
157 	public static final void setConfiguration(WikiConfiguration config){
158 		config_ = config;
159 	}
160 	
161 	public final WikiConfiguration getConfiguration(){
162 		return config_;
163 	}
164 		
165 	public String toString(){
166 		return getClass().getName() + ":" + pluginConfig_.toString();	
167 	}		
168 	// ----- [End] Other public methods -----
169 
170 	public static final String getMessage(String key){
171 		return PluginUtils.getMessage(key);
172 	}
173 	
174 	protected static String getParameterName(String paramName){
175 		return Constants.PARAM_PREFIX_PLUGIN + paramName + Constants.PARAM_SUFFIX_PLUGIN;		
176 	}	
177 
178 	protected static String getJavascriptTemplate(String key){		
179 		return (String)javascriptTemplateMap_.get(key);		
180 	}
181 
182 	protected void initialize(CmsRequest request, CmsResponse response, PluginRequest prequest) throws PluginException{
183 	}	
184 	
185 	protected final void updateArgs(CmsRequest request, CmsResponse response, PluginRequest prequest) throws PluginException{
186 		
187 		String[] args = prequest.getArgs();
188 		String[] updateArgs = null;
189 		if(args != null){
190 			updateArgs = new String[args.length];			
191 			for(int i=0;i<args.length;i++){
192 				Matcher m = INLINEPLUGIN_PATTERN.matcher(args[i]);
193 				if(m.find()){// plugin										
194 					String childPluginName = m.group(1);
195 					String argImage = m.group(2);					
196 					if(config_.isPluginLoaded(childPluginName)){
197 						SimpleNode node = buildNode(childPluginName,argImage);
198 						PluginRequest childPluginRequest = VisitorUtils.createPluginRequest(node);
199 						childPluginRequest.setChild(WikiHelper.deleteParenthesis(argImage,"{","}",false));						
200 						Plugin childPlugin = config_.getPlugin(childPluginName);
201 						Object result = childPlugin.service(request,response,childPluginRequest);
202 						updateArgs[i] = PdfUtils.getStringResult(result);						
203 					}				
204 				}
205 				if(updateArgs[i] == null) updateArgs[i] = args[i];				
206 			}	
207 			prequest.setArgs(updateArgs);
208 		}
209 	}	
210 	
211 	protected final boolean existArg(String[] args, int index) {
212 		return args != null && args.length > index && args[index].length() > 0;
213 	}
214 		
215 	private final void validate(CmsRequest request, CmsResponse response, PluginRequest prequest)
216 	throws PluginException{
217 		// check whether requested mode (Block or Inline) is supported or not.
218 		int requestedmode = prequest.getMode();
219 		if((pluginConfig_.getPluginmode() & requestedmode) == 0)
220 			throw new PluginException("the requested mode [" + requestedmode + "] doesn't support for this plugin.");
221 		
222 		// check argument...		
223 	}
224 	
225 	private static final Map loadTemplate(){		
226 		
227 		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(JAVASCRIPT_TEMPLATE_PATH);		
228 		BufferedReader br = new BufferedReader(new InputStreamReader(is));
229 		Map map = new HashMap();
230 		try{			
231 			boolean startFunction = false;
232 			StringBuffer buf = null;
233 			String name = null;
234 			while(true){				
235 				String line = br.readLine();
236 				if(line == null)
237 					break;
238 				
239 				if(line.startsWith("//"))
240 					continue;
241 				
242 				if(line.startsWith("function")){
243 					startFunction = true;
244 					Matcher m = JAVASCRIPT_FUNCTION_PATTERN.matcher(line);
245 					if(m.find()){
246 						name = m.group(1);
247 					}
248 					buf = new StringBuffer();
249 				}
250 				
251 				if(line.startsWith("};")){
252 					buf.append(line);
253 					map.put(name,buf.toString());
254 					startFunction = false;
255 					name = null;					
256 				}
257 				
258 				if(startFunction){
259 					buf.append(line);
260 				}
261 			}
262 			br.close();
263 			is.close();
264 		}catch(IOException ioe){
265 			classlog_.error("failed to read plugin javascript template file " + JAVASCRIPT_TEMPLATE_PATH);
266 		}		
267 		return map;
268 	}		
269 	
270 	private static SimpleNode buildNode(String pluginName, String argImage){		
271 		int dummyid = 0;
272 		WikiInlinePlugin node = new WikiInlinePlugin(dummyid);
273 		node.name = pluginName;
274 		WikiArgs wargs = new WikiArgs(dummyid);
275 		if(argImage !=null){
276 			wargs.args = WikiHelper.splitArgs(argImage);
277 		}
278 		node.jjtAddChild(wargs,0);
279 		wargs.jjtSetParent(node);
280 		return node;
281 	}
282 	
283 	
284 	//add by nishioka
285 	
286 	private WebAppli appli;
287 	
288 	public void setWebAppli(WebAppli appli) {
289 		this.appli = appli;
290 	}	
291 
292 	public DaoPlugin getDao(){
293 		String siteName = TgwContext.getSiteName();
294 		return appli.getDao(siteName);
295 	}
296 	
297 	public String getActionPath() {
298 		if(appli == null){
299 			return "";
300 		}
301 		return TgwContext.getContextPath() + "/" + TgwContext.getSiteName()
302 				+ "/plugin." + appli.getPath() + ".do";
303 	}
304 		
305 	public String getPageHiddenElement(String pageName){
306 		HtmlBuffer buf = new HtmlBuffer();
307 		buf.appendStartTag(HtmlBuffer.TAG_INPUT);
308 		buf.appendAttribute("type", "hidden");
309 		buf.appendAttribute("name", WebAppli.HIDDEN_PAGE_PARAM);
310 		buf.appendAttribute("value", pageName);
311 		buf.endTag();
312 		return buf.toString();
313 	}
314 	
315 	public String getHiddenElements(CmsRequest request){
316 		HtmlBuffer buf = new HtmlBuffer();
317 		String mainPagePath = request.getMainPagePath();
318 		
319 		buf.appendHidden(WebAppli.HIDDEN_PAGE_PARAM, mainPagePath);
320 		
321 		Iterator itr = request.getParamterNames();
322 		while(itr.hasNext()){
323 			String key = (String)itr.next();
324 			String value = request.getParameter(key);
325 			buf.appendHidden(key, value);
326 		}
327 		return buf.toString();
328 	}
329 	
330 	protected void setPojoClass(Class pojoClass){
331 		appli.setPojoClass(pojoClass);
332 	}
333 	
334 }