1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.system;
17
18 import java.io.ByteArrayInputStream;
19 import java.io.ByteArrayOutputStream;
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.zip.ZipEntry;
27 import java.util.zip.ZipInputStream;
28 import java.util.zip.ZipOutputStream;
29
30 import org.apache.commons.io.FileUtils;
31 import org.apache.commons.io.IOUtils;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.seasar.tuigwaa.cms.ContentsStoreService;
35 import org.seasar.tuigwaa.cms.core.Resource;
36 import org.seasar.tuigwaa.util.MimeMappings;
37 import org.seasar.tuigwaa.util.TgwUtils;
38
39 import com.isenshi.util.PathUtils;
40 import com.isenshi.util.ResourceUtils;
41
42 /***
43 * @author someda
44 */
45 public class DesignServiceImpl implements DesignService {
46
47 private static final String SKIN_TEMPLATE_DIR = "template/skin";
48 private static final String SKIN_DIR = ".SKINS";
49
50 private static final String SYSTEM_SKINPAGE_NAME = "page.html";
51 private static final String[] SYSTEM_AVAILABLE_PAGES = {SYSTEM_SKINPAGE_NAME};
52
53 private ContentsStoreService storeService;
54
55 private Log log = LogFactory.getLog(getClass());
56
57 public DesignServiceImpl(ContentsStoreService storeService){
58 this.storeService = storeService;
59 }
60
61 public void init(){
62 File skinTemplateDir = ResourceUtils.getFile(SKIN_TEMPLATE_DIR);
63 Resource resource = null;
64 try{
65 resource=storeService.getResource(SKIN_DIR,SYSTEM_SKIN_NAME);
66 }catch(TgwSecurityException tse){
67
68 }
69
70 boolean copyFlag = false;
71 if(resource != null){
72 Date lastModifiedDate = resource.getModificationDateAsDate();
73 File[] templates = skinTemplateDir.listFiles();
74 for(int i=0;i<templates.length;i++){
75 if(SYSTEM_SKIN_NAME.equals(templates[i].getName())){
76 if(FileUtils.isFileNewer(templates[i],lastModifiedDate)){
77 copyFlag = true;
78 }
79 break;
80 }
81 }
82 }else{
83 copyFlag = true;
84 }
85
86 if(copyFlag){
87 log.warn("skin template resources are newer than WEB-DAV ones, starting to copy.");
88 try {
89 storeService.copyFromFileSystem(skinTemplateDir, SKIN_DIR);
90 } catch (Exception e) {
91 e.printStackTrace();
92 }
93 }
94 }
95
96 public String[] getAllSkinNames() {
97 String skinNames[] = null;
98 try {
99 List list = storeService.getFolderList(SKIN_DIR, "");
100 skinNames = new String[list.size()];
101 Iterator itr = list.iterator();
102 for (int i = 0; itr.hasNext(); i++) {
103 Resource resource = (Resource) itr.next();
104 if(resource.isFolder()){
105
106 skinNames[i] = resource.getPageName();
107 }
108 }
109 } catch (Exception e) {
110 log.error("failed to load skin names : " + e.getMessage());
111 }
112 return skinNames;
113 }
114
115 public String[] getAvailableSkinNames(String siteName) {
116 return getAllSkinNames();
117 }
118
119 public void uploadSkin(String skinName, ZipInputStream zipInput) throws TgwServiceException {
120
121 boolean isValid = false;
122 ByteArrayOutputStream baos = null;
123 ByteArrayInputStream bais = null;
124
125 try{
126 storeService.createFolder(SKIN_DIR,skinName);
127
128 ZipEntry entry = null;
129 String root = null;
130 while((entry = zipInput.getNextEntry())!= null){
131 String name = entry.getName();
132 if(root == null || !"".equals(root)){
133 root = PathUtils.getRootPath(name);
134 }
135 String relative = PathUtils.getRelativePath(root,name);
136 String uri = skinName + "/" + relative;
137 if(entry.isDirectory()){
138 storeService.createFolder(SKIN_DIR,uri);
139 }else{
140 baos = new ByteArrayOutputStream();
141 int length = 0;
142 int contentLength = 0;
143 int bufsize = 1024;
144 byte[] buf = new byte[bufsize];
145 while(zipInput.available() > 0 && ((length = zipInput.read(buf,0,bufsize)) != -1)){
146 baos.write(buf,0,length);
147 contentLength += length;
148 }
149 bais = new ByteArrayInputStream(baos.toByteArray());
150
151 String extension = PathUtils.getExtension(uri);
152 String contentType = MimeMappings.getContentType(extension);
153 storeService.createResource(SKIN_DIR,uri,contentType,contentLength,bais);
154
155 baos.close();
156 bais.close();
157 }
158 }
159 if(!(isValid = validate(skinName))){
160 throw new TgwServiceException("invalid upload contents for skin : " + skinName);
161 }
162 }catch(IOException ioe){
163 log.error("failed to read input stream : " + ioe.getMessage());
164 }catch(IllegalArgumentException iae){
165 log.error("archive including file with Japanese name not allowed.");
166 throw new TgwServiceException("archive including file with Japanese name not allowed.");
167 }catch(Exception e){
168 log.error(e.getMessage());
169 throw new TgwServiceException(e);
170 }finally{
171 IOUtils.closeQuietly(baos);
172 IOUtils.closeQuietly(bais);
173 if(!isValid){
174 log.error("invalid upload skin : " + skinName);
175 storeService.delete(SKIN_DIR,skinName);
176 }
177 }
178 }
179
180 public void downloadSkin(String skinName, ZipOutputStream zipOutput) throws TgwServiceException {
181
182 try{
183 List resourceList = storeService.getRecursivePageOrFolderList(SKIN_DIR,skinName);
184 for(Iterator i=resourceList.iterator();i.hasNext();){
185 Resource resource = (Resource) i.next();
186 String path = resource.getPath();
187 zipOutput.putNextEntry(new ZipEntry(path));
188 if(!resource.isFolder()){
189 storeService.writeResource(SKIN_DIR,path,zipOutput);
190 }
191 }
192 }catch(IOException ioe){
193 log.error("failed to write output stream : " + ioe.getMessage());
194 }catch(Exception e){
195 log.error(e.getMessage());
196 throw new TgwServiceException(e);
197 }
198 }
199
200 public void deleteSkin(String skinName, List configList) throws TgwServiceException {
201
202 if(SYSTEM_SKIN_NAME.equals(skinName)){
203 throw new TgwServiceException("system default skins (" + skinName + ") cannot be deleted.");
204 }
205
206 for(Iterator i=configList.iterator();i.hasNext();){
207 SiteConfig siteConfig = (SiteConfig) i.next();
208 if(skinName.equals(siteConfig.getSkin())){
209 throw new TgwServiceException("skin (" + skinName + ") being used for site : " + siteConfig.getName());
210 }
211 }
212
213 try{
214 storeService.delete(SKIN_DIR,skinName);
215 }catch(Exception e){
216 throw new TgwServiceException(e);
217 }
218 }
219
220 public void sync(SiteConfig siteConfig, boolean overwrite) throws TgwServiceException {
221
222 String siteName = siteConfig.getName();
223 String skinName = siteConfig.getSkin();
224
225 String siteRootPath = TgwUtils.getTuigwaaActionServlet()
226 .getServletConfig().getServletContext().getRealPath(siteName);
227 File siteRoot = new File(siteRootPath);
228
229 if(!siteRoot.exists()){
230 siteRoot.mkdir();
231 }else if(!overwrite){
232 try{
233 FileUtils.cleanDirectory(siteRoot);
234 }catch(IOException ioe){
235 }
236 }
237
238 try{
239 if(skinName.equals(ARCHIVE_SKIN_NAME)){
240
241 }else{
242 storeService.copyToFileSystem(SKIN_DIR,skinName,siteRoot);
243 }
244 }catch(Exception e){
245 log.error("failed to sync resources : " + e.getMessage());
246 }
247 }
248
249
250 public boolean validate(String skinName){
251
252 boolean flag = false;
253
254 String uri = skinName + "/" + SYSTEM_SKINPAGE_NAME;
255 try{
256 flag = storeService.isExistResource(SKIN_DIR,uri,true);
257 }catch(TgwSecurityException tse){
258
259 tse.printStackTrace();
260 }
261 return flag;
262 }
263
264 public void saveConfig(DesignConfig designConfig) throws TgwServiceException{
265
266 }
267
268 public DesignConfig getDesignConfig(String skinName){
269
270 DesignConfig designConfig = new DesignConfig();
271 designConfig.setName(skinName);
272
273 try{
274 List list = storeService.getPageList(SKIN_DIR,skinName);
275 List availablePageList = new ArrayList();
276 for(Iterator i=list.iterator();i.hasNext();){
277 Resource resource = (Resource)i.next();
278 String pagePath = resource.getPageName();
279 if(resource.isFile() && pagePath.endsWith("html")){
280 availablePageList.add(resource.getPageName());
281 }
282 }
283 int size = availablePageList.size();
284 String[] availablePages;
285 if(size == 0){
286 availablePages = SYSTEM_AVAILABLE_PAGES;
287 }else{
288 availablePages = (String[])availablePageList.toArray(new String[size]);
289 }
290 designConfig.setAvailablePages(availablePages);
291 }catch(Exception e){
292 designConfig.setAvailablePages(SYSTEM_AVAILABLE_PAGES);
293 }
294
295 return designConfig;
296 }
297
298
299
300 }