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;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.util.Properties;
21  
22  import org.apache.commons.io.FileUtils;
23  import org.seasar.framework.log.Logger;
24  import org.seasar.tuigwaa.cms.core.CmsConstants;
25  import org.seasar.tuigwaa.cms.core.CmsContainer;
26  import org.seasar.tuigwaa.cms.core.CmsRequest;
27  import org.seasar.tuigwaa.cms.core.CmsResponse;
28  import org.seasar.tuigwaa.cms.core.Page;
29  import org.seasar.tuigwaa.cms.core.PageImpl;
30  import org.seasar.tuigwaa.cms.core.Resource;
31  import org.seasar.tuigwaa.cms.core.ResourceImpl;
32  import org.seasar.tuigwaa.system.SiteConfig;
33  import org.seasar.tuigwaa.system.TgwException;
34  import org.seasar.tuigwaa.system.TgwSecurityException;
35  import org.seasar.tuigwaa.util.MimeMappings;
36  import org.seasar.tuigwaa.util.TgwContext;
37  import org.seasar.tuigwaa.view.PageComponent;
38  
39  import com.isenshi.util.PathUtils;
40  import com.isenshi.util.ResourceUtils;
41  
42  /***
43   * @author nishioka
44   */
45  public class ContentsServiceImpl implements ContentsService {
46  
47  	private ContentsStoreService storeService;		
48  	private Logger log = Logger.getLogger(getClass());	
49  
50  	private String initPagePath;
51  	private String menuPagePath;
52  	
53  	private static final String WEBDAV_CONTENTPATH = "webdav/content/webfile/";
54  	private static final String WEBDAV_METADATAPATH = "webdav/metadata/webfile/";
55  	
56  	private static final Properties MENU_PROPS = new Properties();
57  	static{
58  		MENU_PROPS.put(CmsConstants.PROPERTY_HIDDEN,"true");
59  	}
60  	
61  	public ContentsServiceImpl(ContentsStoreService slideService) {
62  		this.storeService = slideService;
63  	}
64  
65  	public void setInitPagePath(String initPagePath) {
66  		this.initPagePath = initPagePath;
67  	}
68  
69  	public void setMenuPagePath(String menuPagePath) {
70  		this.menuPagePath = menuPagePath;
71  	}
72  
73  	public PageComponent getPageComponent() throws TgwSecurityException,
74  			TgwResourceNotFoundException {
75  		
76  		String siteName = TgwContext.getSiteName();
77  		String pagePath = TgwContext.getPageName();
78  
79  		Resource res = storeService.getResource(siteName, pagePath);
80  		if (res == null) {
81  			throw new TgwResourceNotFoundException(new Object[]{pagePath,siteName});
82  		}
83  		if (res.isFolder()) {
84  			pagePath = PathUtils.join(pagePath, TgwContext.getSiteConfig()
85  					.getInitPagename());
86  			TgwContext.bindPageName(pagePath);
87  		}
88  
89  		Page page = getPage(siteName, pagePath, CmsConstants.OUTPUTTYPE_HTML);
90  
91  		if (page == null) {
92  			throw new TgwResourceNotFoundException(new Object[]{pagePath,siteName});
93  		}
94  
95  		String menuPagename = getSidePagename(page, true);
96  		Page menu = getPage(siteName, menuPagename,CmsConstants.OUTPUTTYPE_HTML);
97  		String rightPagename = getSidePagename(page, false);
98  		Page right = getPage(siteName, rightPagename,CmsConstants.OUTPUTTYPE_HTML);
99  		
100 		PageComponent pageComponent = new PageComponent();
101 		pageComponent.setMainPage(page);
102 		pageComponent.setLeftMenuPage(menu);	
103 		pageComponent.setRightMenuPage(right);		
104 		
105 		return pageComponent;
106 	}
107 
108 	private Object lock = new Object();
109 
110 	public void savePage(String siteName, String path, String contentType,
111 			Properties props, String content, String editVersion,
112 			String sectionId) throws TgwPageConflictException,
113 			TgwResourceAlreadyExistsException, TgwSecurityException {
114 
115 		synchronized (lock) {
116 			Resource lastResource = storeService.getResource(siteName, path);
117 			if (lastResource != null && lastResource.isFolder()) {
118 				throw new TgwResourceAlreadyExistsException(new Object[]{path});
119 			}
120 			Page lastPage = storeService.getPage(siteName, path);
121 			if (editVersion == null && lastPage != null) {
122 				throw new TgwResourceAlreadyExistsException(new Object[]{path});
123 			} else if (editVersion != null && lastPage != null
124 					&& !editVersion.equals(lastPage.getResource().getVersion())) {
125 				throw new TgwPageConflictException(path,
126 						(String) lastPage.getContent(), lastPage.getResource()
127 								.getVersion());
128 			}
129 			Resource resource = new ResourceImpl(siteName, path, contentType);
130 			if (props != null) {
131 				resource.setProperties(props);
132 			}
133 			Page page = null;
134 			if (sectionId != null && sectionId.length() > 0) {
135 				page = new PageImpl(resource, lastPage.getContent().toString());
136 				page.merge(sectionId, content);
137 			} else {
138 				page = new PageImpl(resource, content);
139 			}
140 			try {
141 				storeService.createPage(page);
142 			} catch (Exception e) {
143 				throw new RuntimeException(e);
144 			}
145 		}
146 	}
147 
148 	public Page getPage(String siteName, String pagePath, int contentType)
149 			throws TgwSecurityException {				
150 		if(pagePath == null){
151 			return null;
152 		}
153 		Page page = getStoredPage(siteName, pagePath);
154 		return doConvert(page, contentType, false);
155 	}
156 
157 	public Page convert(String siteName, String pagePath,
158 			String srcContentType, Object srcContent, int targetContentType) {
159 		return convert(siteName, pagePath, srcContentType, srcContent,
160 				targetContentType, false);
161 	}
162 
163 	public Page convert(String siteName, String pagePath,
164 			String srcContentType, Object srcContent, int targetContentType,
165 			boolean newRequest) {
166 		Resource resource = new ResourceImpl(siteName, pagePath, srcContentType);
167 		resource.setPersistent(false);
168 		Page page = new PageImpl(resource, srcContent);
169 
170 		return doConvert(page, targetContentType, newRequest);
171 	}
172 
173 	public Page doConvert(Page page, int contentType, boolean newRequest) {
174 		if (page == null) {
175 			return null;
176 		}
177 
178 		CmsRequest cmsRequest = (newRequest) ? TgwContext.createNewCmsRequest()
179 				: TgwContext.getCmsRequest();
180 		CmsResponse cmsResponse = TgwContext.getCmsResponse();
181 		String siteName = page.getResource().getSiteName();
182 
183 		cmsRequest.setPage(page);
184 		cmsRequest.setSiteName(siteName);
185 		cmsRequest.setType(contentType);
186 		if (TgwContext.isFullMode()) {
187 			cmsRequest.setMode(CmsConstants.MODE_FULL);
188 		}
189 
190 		CmsContainer.INSTANCE.service(cmsRequest, cmsResponse);
191 
192 		Object content = "";
193 
194 		if (cmsResponse.getBytes() != null) {
195 			content = cmsResponse.getBytes();
196 		} else if (cmsResponse.getString() != null) {
197 			content = cmsResponse.getString();
198 		}
199 
200 		Resource resource = page.getResource().getClone();
201 		String outputType = CmsConstants.getContenttype(cmsRequest.getType());
202 		resource.setContentType(outputType);
203 		return new PageImpl(resource, content);
204 	}
205 
206 
207 	public void createSite(SiteConfig siteConfig) throws TgwSecurityException,TgwResourceAlreadyExistsException{
208 		doCreateFolder(siteConfig, "", true);
209 	}
210 
211 	public void deleteSite(String siteName) throws TgwException{
212 		storeService.delete(siteName, "");
213 	}
214 	
215 	public void copySite(String srcSiteName, String destSiteName) throws TgwException{		
216 		storeService.copy(srcSiteName,null,destSiteName,null);		
217 	}
218 	
219 
220 	public void createFolder(SiteConfig siteConfig, String folderPath)
221 			throws TgwSecurityException, TgwResourceAlreadyExistsException {
222 		doCreateFolder(siteConfig, folderPath, false);
223 	}
224 
225 	public void backup(String siteName, String backupDirectory)
226 			throws TgwException {
227 		
228 		try{
229 			copyContentsFile(siteName,backupDirectory,true);			
230 		}catch(IOException ioe){
231 			throw new TgwException("ETGW0002",new Object[]{siteName,backupDirectory},ioe);			
232 		}
233 	}
234 	
235 	public void restore(String siteName, String backupDirectory)
236 	throws TgwException {		
237 		try{
238 			copyContentsFile(siteName,backupDirectory,false);
239 			storeService.refreshCache(siteName);
240 		}catch(IOException ioe){
241 			throw new TgwException("ETGW0002",new Object[]{siteName,backupDirectory},ioe);
242 		}
243 	}
244 		
245 	// ----- [Start] Private Methods -----		
246 	
247 	/***
248 	 * This is simple implementation, without using Web-DAV API.
249 	 * FIXME: change to use FileUtils#copyDirectoryToDirectory
250 	 */
251 	private void copyContentsFile(String siteName, String backupDirectory, boolean isBackup) throws IOException{
252 				
253 		File contentDir = ResourceUtils.getFile(WEBDAV_CONTENTPATH + siteName);
254 		File metadataDir = ResourceUtils.getFile(WEBDAV_METADATAPATH + siteName);
255 		File metaFile = ResourceUtils.getFile(WEBDAV_METADATAPATH + siteName + ".def.xml");		
256 		File backupDir = ResourceUtils.getFile(backupDirectory);
257 		
258 		if(isBackup){			
259 			ResourceUtils.copyFile(contentDir.getPath(),backupDir.getPath()+ "/" + WEBDAV_CONTENTPATH);
260 			ResourceUtils.copyFile(metadataDir.getPath() + ".def.xml",backupDir.getPath() + "/" + WEBDAV_METADATAPATH);		
261 			ResourceUtils.copyFile(metadataDir.getPath(),backupDir.getPath() + "/" + WEBDAV_METADATAPATH);		
262 		}else{ // restore			
263 			// clean up directory
264 			FileUtils.cleanDirectory(contentDir);
265 			FileUtils.cleanDirectory(metadataDir);
266 			FileUtils.forceDelete(metaFile);
267 			
268 			ResourceUtils.copyFile(backupDir.getPath() + "/" + WEBDAV_CONTENTPATH + siteName, contentDir.getParent());
269 			ResourceUtils.copyFile(backupDir.getPath() + "/" + WEBDAV_METADATAPATH + siteName, metadataDir.getParent());		
270 			ResourceUtils.copyFile(backupDir.getPath() + "/" + WEBDAV_METADATAPATH + siteName + ".def.xml", metadataDir.getParent());			
271 		}
272 	}
273 	
274 	private Page getStoredPage(String siteName, String pageName)
275 			throws TgwSecurityException {
276 		Page page = storeService.getPage(siteName, pageName);
277 		if (page == null) {
278 			log.log("ITGW0001",new Object[]{pageName,siteName});
279 			return null;
280 		}
281 		return page;
282 	}
283 
284 	private String getSidePagename(Page mainPage, boolean isMenupage) {
285 		SiteConfig siteConfig = TgwContext.getSiteConfig();
286 		String pageName = (isMenupage) ? siteConfig.getMenuPagename()
287 				: siteConfig.getRightPagename();
288 		String sidePageName = null;
289 
290 		Properties props = mainPage.getResource().getProperties();
291 		if (props != null) {
292 			sidePageName = (isMenupage) ? props
293 					.getProperty(CmsConstants.PROPERTY_MENUPAGENAME) : props
294 					.getProperty(CmsConstants.PROPERTY_RIGHTPAGENAME);
295 		}
296 		return (sidePageName == null || "".equals(sidePageName)) ? pageName
297 				: sidePageName;
298 	}
299 
300 	private void doCreateFolder(SiteConfig siteConfig, String folder,
301 			boolean isSiteTop) throws TgwSecurityException,TgwResourceAlreadyExistsException{
302 		String siteName = siteConfig.getName();
303 
304 		try {
305 			if (!storeService.isExistResource(siteName, folder, false)) {
306 				storeService.createFolder(siteName, folder);
307 
308 				String path = PathUtils.join(folder, siteConfig
309 						.getInitPagename());
310 				doCopyPage(siteConfig, initPagePath, path, null);
311 
312 				if (isSiteTop) {
313 					Properties props = new Properties();
314 					props.setProperty(CmsConstants.PROPERTY_HIDDEN, "true");
315 					path = PathUtils.join(folder, siteConfig.getMenuPagename());
316 					doCopyPage(siteConfig, menuPagePath, path, props);
317 				}
318 			}else{
319 				throw new TgwResourceAlreadyExistsException(new Object[]{siteName + "/" + folder});
320 			}
321 		}catch(TgwResourceAlreadyExistsException e){
322 			throw e;
323 		}catch(TgwSecurityException tse){
324 			throw tse;
325 		} catch (Exception e) {
326 			e.printStackTrace();
327 			throw new RuntimeException(e);
328 		}
329 	}
330 		
331 	private void doCopyPage(SiteConfig siteConfig, String sourcePath,
332 			String targetPath, Properties props)  throws TgwException{
333 		String siteName = siteConfig.getName();
334 		String contentType = siteConfig.defaultContentType();
335 		String extension = MimeMappings.getExtension(contentType);
336 		String content = ResourceUtils.readContent(sourcePath + "." + extension);
337 		Resource resource = new ResourceImpl(siteName, targetPath, contentType);
338 		if (props != null) {
339 			resource.setProperties(props);
340 		}
341 		Page page = new PageImpl(resource, content);
342 		storeService.createPage(page);
343 	}
344 
345 }