001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.cms.impl.jcr.command;
023:
024: import org.apache.tools.zip.ZipEntry;
025: import org.apache.tools.zip.ZipFile;
026: import org.jboss.portal.cms.CMSException;
027: import org.jboss.portal.cms.impl.ContentImpl;
028: import org.jboss.portal.cms.impl.FileImpl;
029: import org.jboss.portal.cms.impl.FolderImpl;
030: import org.jboss.portal.cms.impl.jcr.JCRCommand;
031: import org.jboss.portal.cms.model.Content;
032: import org.jboss.portal.cms.model.Folder;
033: import org.jboss.portal.cms.util.FileUtil;
034: import org.jboss.portal.cms.util.NodeUtil;
035:
036: import java.io.File;
037: import java.io.FileOutputStream;
038: import java.io.InputStream;
039: import java.util.ArrayList;
040: import java.util.Date;
041: import java.util.Enumeration;
042: import java.util.List;
043: import java.util.Locale;
044: import java.util.StringTokenizer;
045:
046: /**
047: * Saves an uploaded archive to the repo.
048: *
049: * @author <a href="mailto:roy@jboss.org">Roy Russo</a>
050: * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
051: */
052: public class StoreArchiveCommand extends JCRCommand {
053: /** The serialVersionUID */
054: private static final long serialVersionUID = 1568453649437987499L;
055: String msRootPath;
056: InputStream mIS;
057: String msLanguage;
058:
059: /**
060: * @param sRootPath
061: * @param is
062: * @param sLanguage
063: */
064: public StoreArchiveCommand(String sRootPath, InputStream is,
065: String sLanguage) {
066: this .msRootPath = sRootPath;
067: this .mIS = is;
068: this .msLanguage = sLanguage;
069: }
070:
071: /**
072: *
073: */
074: public Object execute() {
075: List contents = new ArrayList();
076: File tmpFile = null;
077: try {
078: tmpFile = this .getZipFile();
079:
080: ZipFile zipFile = new ZipFile(tmpFile);
081: ZipEntry zipEntry;
082: Enumeration entries = zipFile.getEntries();
083: while (entries.hasMoreElements()) {
084: zipEntry = (ZipEntry) entries.nextElement();
085: String itemName = zipEntry.getName();
086: if (!zipEntry.isDirectory()) {
087: long fileSize = zipEntry.getSize();
088: byte[] zipBytes = new byte[(int) fileSize];
089: InputStream zipDataStream = zipFile
090: .getInputStream(zipEntry);
091: long bytesRead = 0;
092:
093: while (bytesRead < fileSize) {
094: bytesRead += zipDataStream.read(zipBytes,
095: (int) bytesRead,
096: (int) (fileSize - bytesRead));
097: }
098:
099: org.jboss.portal.cms.model.File file = new FileImpl();
100:
101: String sBasePath = FileUtil.cleanDoubleSlashes("/"
102: + this .msRootPath + "/" + itemName);
103: sBasePath = FileUtil.cleanDoubleSlashes(sBasePath); // hackish, but necessary for root path uploads.
104: file.setBasePath(sBasePath);
105:
106: Content content = new ContentImpl();
107: content.setEncoding("UTF-8");
108: content.setTitle(itemName);
109: content.setDescription(itemName);
110: content.setBasePath(sBasePath + "/"
111: + this .msLanguage);
112: content.setBytes(zipBytes);
113: file.setContent(new Locale(this .msLanguage),
114: content);
115:
116: // in case folder does not exist, yet.
117: String sParentPath = NodeUtil
118: .getParentPath(sBasePath);
119: JCRCommand nodeExists = (JCRCommand) context
120: .getCommandFactory()
121: .createItemExistsCommand(sParentPath);
122: Boolean bExists = (Boolean) context
123: .execute(nodeExists);
124: if (!bExists.booleanValue()) {
125: this .createParentHierarchy(sParentPath);
126: }
127:
128: JCRCommand fileSave = (JCRCommand) context
129: .getCommandFactory().createFileSaveCommand(
130: file);
131: context.execute(fileSave);
132:
133: JCRCommand saveContentCMD = (JCRCommand) context
134: .getCommandFactory()
135: .createContentSaveCommand(file);
136: context.execute(saveContentCMD);
137:
138: contents.add(content);
139: } else // isDirectory
140: {
141: // trim trailing slash.
142: if (itemName.endsWith("/")) {
143: itemName = itemName.substring(0, itemName
144: .length() - 1);
145: }
146:
147: if (!"".equals(itemName)) {
148: String sBasePath = FileUtil
149: .cleanDoubleSlashes("/"
150: + this .msRootPath + "/"
151: + itemName);
152: sBasePath = FileUtil
153: .cleanDoubleSlashes(sBasePath); // hackish, but necessary for root path uploads.
154: String sParentPath = NodeUtil
155: .getParentPath(sBasePath);
156: JCRCommand nodeExists = (JCRCommand) context
157: .getCommandFactory()
158: .createItemExistsCommand(sParentPath);
159: Boolean bExists = (Boolean) context
160: .execute(nodeExists);
161: if (!bExists.booleanValue()) {
162: this .createParentHierarchy(sParentPath);
163: }
164:
165: JCRCommand nodeExists2 = (JCRCommand) context
166: .getCommandFactory()
167: .createItemExistsCommand(sBasePath);
168: Boolean bExists2 = (Boolean) context
169: .execute(nodeExists2);
170: if (!bExists2.booleanValue()) {
171: Folder folder = new FolderImpl();
172: folder.setName(itemName);
173: folder.setDescription(itemName);
174: folder.setTitle(itemName);
175: folder.setLastModified(new Date());
176: folder.setBasePath(sBasePath);
177:
178: JCRCommand folderSave = (JCRCommand) context
179: .getCommandFactory()
180: .createFolderSaveCommand(folder);
181: context.execute(folderSave);
182: }
183: }
184: }
185: }
186: return contents;
187: } catch (Exception e) {
188: e.printStackTrace();
189: } finally {
190: if (tmpFile != null) {
191: tmpFile.delete();
192: }
193: }
194: return null;
195: }
196:
197: /** @param parentPath */
198: private void createParentHierarchy(String parentPath)
199: throws CMSException {
200: StringTokenizer tokenizer = new StringTokenizer(parentPath, "/");
201:
202: StringBuffer buffer = new StringBuffer("/");
203: while (tokenizer.hasMoreTokens()) {
204: buffer.append(tokenizer.nextToken());
205: String cour = buffer.toString();
206:
207: JCRCommand nodeExists = (JCRCommand) context
208: .getCommandFactory().createItemExistsCommand(cour);
209: Boolean bExists = (Boolean) context.execute(nodeExists);
210: if (!bExists.booleanValue()) {
211: this .createFolder(cour);
212: }
213:
214: if (tokenizer.hasMoreTokens()) {
215: buffer.append("/");
216: }
217: }
218: }
219:
220: /**
221: * @param folderPath
222: * @throws CMSException
223: */
224: private void createFolder(String folderPath) throws CMSException {
225: Folder folder = new FolderImpl();
226: folder.setName(folderPath);
227: folder.setDescription(folderPath);
228: folder.setTitle(folderPath);
229: folder.setLastModified(new Date());
230: folder.setBasePath(folderPath);
231:
232: JCRCommand parentSave = (JCRCommand) context
233: .getCommandFactory().createFolderSaveCommand(folder);
234: context.execute(parentSave);
235: }
236:
237: /** @return */
238: private File getZipFile() throws Exception {
239: File zipFile = null;
240:
241: zipFile = File.createTempFile("jbportal_", "_cmsimport.zip");
242: FileOutputStream fos = new FileOutputStream(zipFile
243: .getCanonicalPath());
244: try {
245: int count;
246: byte[] data = new byte[1024];
247: while ((count = this .mIS.read(data, 0, 1024)) != -1) {
248: fos.write(data, 0, count);
249: fos.flush();
250: }
251: } finally {
252: fos.close();
253: }
254:
255: return zipFile;
256: }
257: }
|