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.controller;
17  
18  import java.io.OutputStream;
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Properties;
25  
26  import javax.servlet.RequestDispatcher;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  import javax.servlet.http.HttpSession;
30  
31  import org.apache.commons.beanutils.PropertyUtils;
32  import org.apache.commons.lang.ArrayUtils;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.apache.struts.action.ActionForm;
36  import org.apache.struts.action.ActionForward;
37  import org.apache.struts.action.ActionMapping;
38  import org.apache.struts.action.ActionMessage;
39  import org.apache.struts.action.ActionMessages;
40  import org.apache.struts.actions.MappingDispatchAction;
41  import org.seasar.tuigwaa.cms.ContentsService;
42  import org.seasar.tuigwaa.cms.ContentsStoreService;
43  import org.seasar.tuigwaa.cms.TgwPageConflictException;
44  import org.seasar.tuigwaa.cms.TgwResourceAlreadyExistsException;
45  import org.seasar.tuigwaa.cms.TgwResourceNotFoundException;
46  import org.seasar.tuigwaa.cms.core.CmsConstants;
47  import org.seasar.tuigwaa.cms.core.Page;
48  import org.seasar.tuigwaa.cms.core.Resource;
49  import org.seasar.tuigwaa.cms.core.wiki.base.WikiHelper;
50  import org.seasar.tuigwaa.model.ModelService;
51  import org.seasar.tuigwaa.model.core.TgwEntity;
52  import org.seasar.tuigwaa.plugin.TgwPluginUtils;
53  import org.seasar.tuigwaa.system.Constants;
54  import org.seasar.tuigwaa.system.SiteConfig;
55  import org.seasar.tuigwaa.system.TgwSecurityException;
56  import org.seasar.tuigwaa.util.TgwContext;
57  import org.seasar.tuigwaa.util.TgwResource;
58  import org.seasar.tuigwaa.util.TgwUtils;
59  import org.seasar.tuigwaa.view.EntityFormComponent;
60  import org.seasar.tuigwaa.view.HtmlService;
61  import org.seasar.tuigwaa.view.JspEngine;
62  import org.seasar.tuigwaa.view.PageComponent;
63  
64  import com.isenshi.util.Diff;
65  import com.isenshi.util.HttpUtils;
66  import com.isenshi.util.PathUtils;
67  import com.isenshi.util.ResourceUtils;
68  import com.isenshi.util.extlib.StrutsUtil;
69  
70  /***
71   * @author nishioka
72   */
73  public class PageAction extends MappingDispatchAction {
74  
75  	private static final String[] PAGE_EXTENTIONS = { "", "html", "wiki" };
76  
77  	private Log log = LogFactory.getLog(getClass());
78  
79  	private ContentsStoreService contentsStoreService;
80  
81  	private ContentsService contentsService;
82  
83  	private ModelService modelService;
84  
85  	private HtmlService htmlService;
86  
87  	private static final String[] CMS_RELAY_PARAMETERS = {
88  			Constants.PARAM_PREFIX_ENTITY, Constants.PARAM_PREFIX_PLUGIN };
89  
90  	private static final Map FORWARDS;
91  	
92  	private static boolean OPT_NOPAGE_CREATE = true;
93  
94  	static {
95  		Map map = new HashMap();
96  		map.put(CmsConstants.CONTENTTYPE_XWIKI, "pageForm");
97  		map.put(CmsConstants.CONTENTTYPE_HTML, "pageFormWysiwyg");
98  		map.put(CmsConstants.CONTENTTYPE_DFORM, "pageFormDesignForm");
99  		FORWARDS = Collections.unmodifiableMap(map);
100 		
101 		OPT_NOPAGE_CREATE = "true".equalsIgnoreCase(TgwResource.getProperty("option.nopage.create"));
102 	}
103 
104 	public PageAction(ContentsStoreService slideService,
105 			ContentsService wikiService, ModelService entityService,
106 			HtmlService htmlService) {
107 		this.contentsStoreService = slideService;
108 		this.contentsService = wikiService;
109 		this.modelService = entityService;
110 		this.htmlService = htmlService;
111 	}
112 
113 	public ActionForward view(ActionMapping mapping, ActionForm form,
114 			HttpServletRequest request, HttpServletResponse response)
115 			throws Exception {
116 		
117 		TgwContext.initPageName();
118 		String pagePath = TgwContext.getPageName();
119 		String extention = PathUtils.getExtension(pagePath);
120 
121 		if (ArrayUtils.contains(PAGE_EXTENTIONS, extention)) {
122 			return doViewPage(mapping, form, request, response);
123 		} else {
124 			return doViewResource(mapping, form, request, response);
125 		}
126 	}
127 
128 	public ActionForward save(ActionMapping mapping, ActionForm form,
129 			HttpServletRequest request, HttpServletResponse response)
130 			throws Exception {
131 		return doPageSave(mapping, form, request, response);
132 	}
133 
134 	public ActionForward edit(ActionMapping mapping, ActionForm form,
135 			HttpServletRequest request, HttpServletResponse response)
136 			throws Exception {
137 		String siteName = TgwContext.getSiteName();
138 
139 		// Create Page Form
140 		String pagename = TgwContext.getPageName();
141 		Page page = contentsStoreService.getPage(siteName, pagename);
142 
143 		// check whether page is locked or not
144 		if (isPageLocked(page)) {
145 			log.warn(pagename + " locked.");
146 			ActionMessages msgs = new ActionMessages();
147 			msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
148 					"msgs.page.locked"));
149 			saveMessages(request, msgs);
150 			return mapping.findForward("usererror");
151 		}
152 
153 		PageForm pform = new PageForm(siteName, page.getResource()
154 				.getParentPath());
155 
156 		String content = null;
157 		String sectionId = request.getParameter(Constants.PARAM_PAGESECTIONID);
158 
159 		if (sectionId != null && sectionId.length() > 0) {
160 			pform.setSectionId(sectionId);
161 			content = page.retrieve(sectionId);
162 		} else {
163 			content = page.getContent().toString();
164 		}
165 		pform.setContent(content);
166 
167 		List attachmentList = contentsStoreService.getAttachmentFileList(
168 				siteName, pagename);
169 		pform.setAttachmentList(attachmentList);
170 
171 		pform.setName(page.getResource().getPageName());
172 		pform.setSaved(true);
173 		pform.setLastVersion(page.getResource().getVersion());
174 		pform.setContentType(page.getResource().getContentType());
175 		return doPageEdit(mapping, form, request, response, pform, "success");
176 	}
177 
178 	public ActionForward createNew(ActionMapping mapping, ActionForm form,
179 			HttpServletRequest request, HttpServletResponse response)
180 			throws Exception {
181 		boolean byNameFlag = "true".equals(request
182 				.getParameter(Constants.PARAM_BYNAME));
183 		return doCreateNew(mapping, form, request, response, byNameFlag);
184 	}
185 
186 	public ActionForward createNewByName(ActionMapping mapping,
187 			ActionForm form, HttpServletRequest request,
188 			HttpServletResponse response) throws Exception {
189 		return doCreateNew(mapping, form, request, response, true);
190 	}
191 
192 	// [Start] ----- Private Action Method ------
193 
194 	private ActionForward doPageSave(ActionMapping mapping, ActionForm form,
195 			HttpServletRequest request, HttpServletResponse response)
196 			throws Exception {
197 
198 		// Get Page Information
199 		String siteName = TgwContext.getSiteName();
200 		PageForm pform = (PageForm) form;
201 		String content = pform.getContent();
202 		String name = pform.getName();
203 		String folder = pform.getFolder();
204 		String contentType = pform.getContentType();
205 		String path = (folder.equals("")) ? name : PathUtils.join(folder, name);
206 		String editVersion = pform.getLastVersion();
207 		String sectionId = pform.getSectionId();
208 		content = WikiHelper.beforeSavePage(contentType, content);
209 
210 		// page save
211 		try {
212 			if (CmsConstants.CONTENTTYPE_DFORM.equals(contentType)) {
213 				String entityName = pform.getSettings().getProperty("entity");
214 				ResourceUtils.writeContent("app/" + siteName + "/formtemplate/"
215 						+ entityName + "/" + name + ".jsp", content);
216 			} else {
217 				contentsService.savePage(siteName, path, contentType, pform
218 						.getSettings(), content, editVersion, sectionId);
219 			}
220 		} catch (TgwResourceAlreadyExistsException e) {
221 			ActionMessages msgs = new ActionMessages();
222 			msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
223 					"msg.folderForm.duplicate"));
224 			saveMessages(request, msgs);
225 			return mapping.findForward("conflict");
226 		} catch (TgwPageConflictException e) {
227 			pform.setConflictedText(e.getConflictedText());
228 			pform.setLastVersion(e.getLastVersion());
229 			return mapping.findForward("conflict");
230 		}
231 
232 		// after page saved
233 		TgwContext.bindPageName(path);
234 		StrutsUtil.clearSessionForm(request, mapping);
235 		return mapping.findForward("success");
236 	}
237 
238 	private ActionForward doCreateNew(ActionMapping mapping, ActionForm form,
239 			HttpServletRequest request, HttpServletResponse response,
240 			boolean byName) throws Exception {
241 
242 		// get page info
243 		String pageName = TgwContext.getPageName();
244 		String parentPath = PathUtils.getParentPath(pageName);
245 		SiteConfig siteConfig = TgwContext.getSiteConfig();
246 		String siteName = siteConfig.getName();
247 		String contentType = request.getParameter(Constants.PARAM_CONTENTTYPE);
248 
249 		// set page info to PageForm
250 		PageForm pageForm = new PageForm(siteName, parentPath + "/");
251 		contentType = checkContentType(contentType, siteConfig, pageForm,
252 				request);
253 		pageForm.setContentType(contentType);
254 		if (byName) {
255 			pageForm.setName(PathUtils.getResourceName(pageName));
256 		}
257 		String initContent = getInitialContent(mapping, form, request,
258 				response, contentType);
259 		pageForm.setContent(initContent);
260 
261 		return doPageEdit(mapping, form, request, response, pageForm, "success");
262 	}
263 
264 	private ActionForward doPageEdit(ActionMapping mapping, ActionForm form,
265 			HttpServletRequest request, HttpServletResponse response,
266 			PageForm pageForm, String forward) throws Exception {
267 
268 		TgwContext.relayToCmsParameter(new String[] {
269 				Constants.PARAM_PREFIX_ENTITY, Constants.PARAM_PREFIX_PLUGIN });
270 
271 		String siteName = TgwContext.getSiteName();
272 
273 		// Binding Common Entity Information
274 		Map entityNameMap = TgwPluginUtils.getEntityNameMapFromRequest(request);
275 		bindSelectedEntityMap(pageForm, entityNameMap, request);
276 		bindEntityInfo(pageForm, request);
277 
278 		List folderList = contentsStoreService.getRecursiveFolderList(siteName,
279 				"");
280 
281 		pageForm.setFolderList(folderList);
282 
283 		Properties settings = (Properties) request
284 				.getAttribute(Constants.RATTR_PAGESETTINGS);
285 		if (settings != null) {
286 			pageForm.setSettings(settings);
287 		}
288 
289 		bindPageForm(request, pageForm);
290 
291 		String forwardName = (String) FORWARDS.get(pageForm.getContentType());
292 		return mapping.findForward(forwardName);
293 	}
294 
295 	// [End] ----- Privata Action Method ------
296 
297 	// [Start] ----- Site Management Method (history, diff, seach)------
298 
299 	public ActionForward viewHistory(ActionMapping mapping, ActionForm form,
300 			HttpServletRequest request, HttpServletResponse response)
301 			throws Exception {
302 
303 		String siteName = TgwContext.getSiteName();
304 		String pagePath = (String) request
305 				.getAttribute(Constants.RATTR_PAGENAME);
306 		List list = contentsStoreService.getHistory(siteName, pagePath);
307 
308 		request.setAttribute(Constants.RATTR_PAGEHISTORY, list);
309 		return mapping.findForward("success");
310 	}
311 
312 	public ActionForward diff(ActionMapping mapping, ActionForm form,
313 			HttpServletRequest request, HttpServletResponse response)
314 			throws Exception {
315 		String version = request.getParameter(Constants.PARAM_PAGE_VERSION);
316 		String siteName = TgwContext.getSiteName();
317 		String pagePath = (String) request
318 				.getAttribute(Constants.RATTR_PAGENAME);
319 		Diff diff = contentsStoreService.getDiff(siteName, pagePath, version);
320 		request.setAttribute(Constants.RATTR_PAGEDIFF, diff);
321 		return mapping.findForward("success");
322 	}
323 
324 	public ActionForward search(ActionMapping mapping, ActionForm form,
325 			HttpServletRequest request, HttpServletResponse response)
326 			throws Exception {
327 		String siteName = TgwContext.getSiteName();
328 		// String keyword = StrutsUtil.getURLDecodedParameter(request,
329 		// "keyword");
330 		String keyword = (String) PropertyUtils.getProperty(form, "keyword");
331 		List pageList = contentsStoreService.search(siteName, keyword);
332 		request.setAttribute(Constants.RATTR_PAGELIST, pageList);		
333 		String result = JspEngine.parse("/WEB-INF/parts/sitemanage/pageSearchList.jsp");
334 		request.setAttribute(Constants.RATTR_MANAGE_MAINPATH,result);		
335 		request.setAttribute(Constants.RATTR_PAGENAME,TgwResource.getMessage("title.label.searchPage"));
336 				
337 		return mapping.findForward("success");
338 	}
339 
340 	// [End] ----- Site Management Method (history, diff, seach)------
341 
342 	// [Start] ------ Private Method ------
343 
344 	public ActionForward doViewResource(ActionMapping mapping, ActionForm form,
345 			HttpServletRequest request, HttpServletResponse response)
346 			throws Exception {
347 
348 		String siteName = TgwContext.getSiteName();
349 		String pagePath = TgwContext.getPageName();
350 		
351 		Resource resource = contentsStoreService.getResource(siteName, pagePath);
352 
353 		if (resource != null) {
354 			HttpUtils.setResponseHeader(request, response, resource.getContentType());
355 			OutputStream os = response.getOutputStream();
356 			contentsStoreService.writeResource(siteName, pagePath,  os);
357 			os.close();
358 		} else {
359 			//String uri = request.getServletPath();
360 			String uri = "/" + PathUtils.join(siteName, pagePath);
361 			RequestDispatcher rd = request.getRequestDispatcher(uri);
362 			rd.forward(request, response);
363 		}
364 		return null;
365 	}
366 
367 	public ActionForward doViewPage(ActionMapping mapping, ActionForm form,
368 			HttpServletRequest request, HttpServletResponse response)
369 			throws Exception {
370 
371 		TgwContext.relayToCmsParameter(CMS_RELAY_PARAMETERS);
372 		String keyword = StrutsUtil.getURLDecodedParameter(request,
373 				Constants.PARAM_KEYWORD);
374 		TgwPluginUtils.bindKeyword(keyword);
375 		TgwContext.initPageName();
376 
377 		PageComponent pageComponent = null;
378 		try {
379 			pageComponent = contentsService.getPageComponent();
380 		} catch (TgwResourceNotFoundException e) {						
381 			SiteConfig siteConfig = TgwContext.getSiteConfig();
382 			if(siteConfig.isPageManageFlag() || OPT_NOPAGE_CREATE){				
383 				String forward = getViewpageForward(pageComponent, true, mapping);
384 				return mapping.findForward(forward);				
385 			}else{
386 				log.warn("");
387 				response.sendError(HttpServletResponse.SC_NOT_FOUND,"");
388 				return null;
389 			}			
390 
391 		} catch (TgwSecurityException e) {
392 			String remoteUser = request.getRemoteUser();
393 			if (remoteUser == null || remoteUser.equals("")) {
394 				return (ActionForward) mapping.getModuleConfig()
395 						.findForwardConfig("login");
396 			} else {
397 				log.warn("Access Deneied for " + remoteUser);
398 				response.sendError(HttpServletResponse.SC_FORBIDDEN, "");
399 				return null;
400 			}
401 		}
402 		request.setAttribute(Constants.RATTR_HTML_PAGE, pageComponent);		
403 		Page mainPage = pageComponent.getMainPage();
404 		setAttachmentList(request);
405 		setPageLock(request,mainPage);
406 		setLastPagePath(request,mainPage);
407 
408 		String forward = getViewpageForward(pageComponent, false, mapping);
409 		if ("true".equals(request.getParameter(Constants.PARAM_FULLMODE))) {
410 			forward = "full";
411 		}
412 		return mapping.findForward(forward);
413 	}
414 
415 	private String checkContentType(String contentType, SiteConfig siteConfig,
416 			PageForm pageForm, HttpServletRequest request) {
417 		if (contentType != null) {
418 			if ("dform".equals(contentType)) {
419 				contentType = CmsConstants.CONTENTTYPE_DFORM;
420 				Properties props = new Properties();
421 				props.put("entity", TgwUtils.getEntity(request, getServlet())
422 						.getName());
423 				pageForm.setSettings(props);
424 			} else if ("wiki".equals(contentType)) {
425 				contentType = CmsConstants.CONTENTTYPE_XWIKI;
426 			} else {
427 				contentType = CmsConstants.CONTENTTYPE_HTML;
428 			}
429 		} else {
430 			contentType = siteConfig.defaultContentType();
431 		}
432 		return contentType;
433 	}
434 
435 	private void bindPageForm(HttpServletRequest request, PageForm pageForm) {
436 		request.getSession().setAttribute(Constants.SATTR_PAGEFORM, pageForm);
437 	}
438 
439 	private void bindEntityInfo(PageForm pageForm, HttpServletRequest request) {
440 		String siteName = TgwContext.getSiteName();
441 		List list = modelService.createEntityInfoList(siteName);
442 		pageForm.setEntityInfoList(list);
443 	}
444 
445 	private void bindSelectedEntityMap(PageForm pageForm,
446 			Map selectedEntityNameMap, HttpServletRequest request) {
447 		String siteName = TgwContext.getSiteName();
448 		Map selectedEntityMap = new HashMap();
449 
450 		for (Iterator i = selectedEntityNameMap.keySet().iterator(); i
451 				.hasNext();) {
452 			String entityName = (String) i.next();
453 			TgwEntity entity = modelService.getEntity(siteName, entityName);
454 			selectedEntityMap
455 					.put(entity, selectedEntityNameMap.get(entityName));
456 		}
457 		pageForm.setSelectedEntityMap(selectedEntityMap);
458 	}
459 
460 	// return forward name
461 	private String getViewpageForward(PageComponent pageComponent,
462 			boolean isNopage, ActionMapping mapping) {
463 		
464 		if(isNopage){
465 			return "nopage";			
466 		}
467 		
468 		Page mainPage = pageComponent.getMainPage();
469 		Resource resource = mainPage.getResource();
470 		String skinPagename = resource.getProperty(CmsConstants.PROPERTY_SKINPAGENAME);
471 			
472 		if(skinPagename == null || "".equals(skinPagename)){
473 			return Constants.LOCAL_FORWARD_SUCCESS;
474 		}
475 				
476 		String forward = Constants.LOCAL_FORWARD_SUCCESS;
477 		if(! "".equals(skinPagename) && mapping.findForward(skinPagename) !=null){
478 			forward = skinPagename;
479 		}		
480 		return forward;
481 	}
482 
483 	private boolean isPageLocked(Page page) {
484 		Resource resource = page.getResource();
485 		return resource.getProperty(CmsConstants.PROPERTY_LOCKUSER) != null;
486 	}
487 
488 	public String getInitialContent(ActionMapping mapping, ActionForm form,
489 			HttpServletRequest request, HttpServletResponse response,
490 			String contentType) throws Exception {
491 		if (contentType.equals(CmsConstants.CONTENTTYPE_DFORM)) {
492 			TgwEntity entity = TgwUtils.getEntity(request, getServlet());
493 			EntityFormComponent formComponent = htmlService
494 					.createFormComponent(entity, null);
495 			formComponent.setNeedJavaScript(false);
496 			formComponent.setJspTemplate(true);
497 
498 			String forwardPageName = "${bean.forwardPageName}";
499 			formComponent.setForwardPageName(forwardPageName);
500 			return htmlService.toHtml(formComponent);
501 		}
502 		return "";
503 	}
504 
505 	// set upload file list
506 	private void setAttachmentList(HttpServletRequest request){
507 		
508 		String siteName = TgwContext.getSiteName();
509 		String pageName = TgwContext.getPageName();		
510 		try {
511 			List uploadFileList = 
512 				contentsStoreService.getAttachmentFileList(siteName, pageName);
513 			request.setAttribute(Constants.RATTR_UPLOADFILELIST,
514 							uploadFileList);
515 		} catch (TgwSecurityException e) {
516 			log.info("failed to get upload file with security system.");
517 		}
518 	}
519 
520 	// set lock
521 	private void setPageLock(HttpServletRequest request, Page page){
522 		if (isPageLocked(page)) {
523 			request.setAttribute(Constants.RATTR_PAGELOCK, "true");
524 		}
525 	}
526 
527 	// set last page path
528 	private void setLastPagePath(HttpServletRequest request, Page page){
529 		String pagePath = page.getResource().getPageName();
530 		HttpSession session = request.getSession();
531 		session.setAttribute(Constants.SATTR_LASTPAGEPATH,pagePath);		
532 	}
533 		
534 	// [End] ------ Private Method ------
535 }