001: /**
002: * LibreSource
003: * Copyright (C) 2004-2008 Artenum SARL / INRIA
004: * http://www.libresource.org - contact@artenum.com
005: *
006: * This file is part of the LibreSource software,
007: * which can be used and distributed under license conditions.
008: * The license conditions are provided in the LICENSE.TXT file
009: * at the root path of the packaging that enclose this file.
010: * More information can be found at
011: * - http://dev.libresource.org/home/license
012: *
013: * Initial authors :
014: *
015: * Guillaume Bort / INRIA
016: * Francois Charoy / Universite Nancy 2
017: * Julien Forest / Artenum
018: * Claude Godart / Universite Henry Poincare
019: * Florent Jouille / INRIA
020: * Sebastien Jourdain / INRIA / Artenum
021: * Yves Lerumeur / Artenum
022: * Pascal Molli / Universite Henry Poincare
023: * Gerald Oster / INRIA
024: * Mariarosa Penzi / Artenum
025: * Gerard Sookahet / Artenum
026: * Raphael Tani / INRIA
027: *
028: * Contributors :
029: *
030: * Stephane Bagnier / Artenum
031: * Amadou Dia / Artenum-IUP Blois
032: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
033: */package org.libresource.web.controllers.so6;
034:
035: import org.libresource.Libresource;
036:
037: import org.libresource.core.FileData;
038:
039: import org.libresource.kernel.KernelConstants;
040: import org.libresource.kernel.LibresourceSecurityException;
041: import org.libresource.kernel.interfaces.KernelService;
042:
043: import org.libresource.membership.MembershipConstants;
044: import org.libresource.membership.interfaces.MembershipService;
045:
046: import org.libresource.so6.core.command.Command;
047: import org.libresource.so6.core.command.text.AddBlock;
048: import org.libresource.so6.core.command.text.DelBlock;
049: import org.libresource.so6.core.engine.OpVectorFsImpl;
050: import org.libresource.so6.core.engine.PatchFile;
051: import org.libresource.so6.core.engine.util.FileBrowserPatchHandler;
052: import org.libresource.so6.core.engine.util.FileUtils;
053: import org.libresource.so6.server.ls.LibresourceSynchronizerConstants;
054: import org.libresource.so6.server.ls.PatchBean;
055: import org.libresource.so6.server.ls.ejb.LibresourceSynchronizerServiceBean;
056: import org.libresource.so6.server.ls.ejb.model.SynchronizerResourceValue;
057: import org.libresource.so6.server.ls.ejb.model.WsConnectionResourceValue;
058: import org.libresource.so6.server.ls.interfaces.LibresourceSynchronizerService;
059:
060: import org.libresource.web.Controller;
061: import org.libresource.web.Helper;
062: import org.libresource.web.config.Config;
063:
064: import java.io.File;
065: import java.io.FileInputStream;
066: import java.io.FileOutputStream;
067: import java.io.InputStream;
068: import java.io.OutputStream;
069:
070: import java.net.URI;
071:
072: import java.util.ArrayList;
073: import java.util.Arrays;
074: import java.util.Collection;
075: import java.util.Iterator;
076: import java.util.ListIterator;
077: import java.util.Properties;
078:
079: import javax.servlet.http.HttpServletRequest;
080: import javax.servlet.http.HttpServletResponse;
081:
082: public class SynchronizerController implements Controller {
083: public Object process(URI uri, HttpServletRequest request,
084: HttpServletResponse response) throws Exception {
085: LibresourceSynchronizerService libresourceSycnhronizerService = (LibresourceSynchronizerService) Libresource
086: .getService(LibresourceSynchronizerConstants.SERVICE);
087: SynchronizerResourceValue synchronizerResourceValue = libresourceSycnhronizerService
088: .getSynchronizer(uri);
089: request.setAttribute("synchronizer", synchronizerResourceValue);
090:
091: // check security
092: MembershipService membershipService = (MembershipService) Libresource
093: .getService(MembershipConstants.SERVICE);
094: KernelService kernelService = (KernelService) Libresource
095: .getService(KernelConstants.SERVICE);
096: request
097: .setAttribute(
098: "canCreateReplica",
099: new Boolean(
100: Helper
101: .checkSecurity(
102: uri,
103: LibresourceSynchronizerServiceBean.SO6_CREATE_WORKSPACE)));
104:
105: PatchBean[] compressedPatchList = libresourceSycnhronizerService
106: .listSynchronizerPatch(uri, 1);
107: request.setAttribute("canBrowse", new Boolean(
108: compressedPatchList.length > 0));
109:
110: // retreive view information
111: if ((request.getParameter("view") == null)
112: || "workspace".equals(request.getParameter("view"))) {
113: // View replica list
114: WsConnectionResourceValue[] replicas = libresourceSycnhronizerService
115: .listSynchronizerConnections(uri);
116: request.setAttribute("replicas", replicas);
117: request.setAttribute("replicaView", Boolean.TRUE);
118: } else if ("history".equals(request.getParameter("view"))
119: || "tags".equals(request.getParameter("view"))) {
120: // View patch history
121: PatchBean[] patchList = libresourceSycnhronizerService
122: .listSynchronizerPatch(uri, 0);
123: request.setAttribute("patches", patchList);
124: request.setAttribute("patchView", Boolean.TRUE);
125: } else if ("browse".equals(request.getParameter("view"))) {
126: if (!kernelService.checkSecurity(uri,
127: KernelConstants.SECURITY_READ)) {
128: throw new LibresourceSecurityException(uri,
129: KernelConstants.SECURITY_READ);
130: }
131:
132: long fromTicket = compressedPatchList[0].getFromTicket();
133: long toTicket = compressedPatchList[0].getToTicket();
134:
135: if ((request.getParameter("from") != null)
136: && (request.getParameter("to") != null)) {
137: fromTicket = Long.parseLong(request
138: .getParameter("from"));
139: toTicket = Long.parseLong(request.getParameter("to"));
140: }
141:
142: String fileName = request.getParameter("fileName");
143:
144: //
145: String baseWorkingDir = LibresourceSynchronizerServiceBean
146: .getSynchronizerBasePath(synchronizerResourceValue
147: .getId())
148: + File.separator + fromTicket + "_" + toTicket;
149: File propFile = new File(baseWorkingDir,
150: "attach.properties");
151:
152: if (fileName != null) {
153: // download file name
154: Properties props = new Properties();
155: FileInputStream fis = new FileInputStream(propFile);
156: props.load(fis);
157: fis.close();
158:
159: File fileToDownload = new File(baseWorkingDir, props
160: .getProperty(fileName));
161: response
162: .setContentLength((int) fileToDownload.length());
163: response.setContentType("application/octetstream");
164: response.addHeader("Content-Disposition",
165: "attachment; filename="
166: + new File(fileName).getName()
167: .replaceAll(" ", "_"));
168:
169: // set body
170: OutputStream out = response.getOutputStream();
171: fis = new FileInputStream(fileToDownload);
172:
173: byte[] buffer = new byte[1024 * 1024];
174: int length = -1;
175:
176: while ((length = fis.read(buffer)) != -1) {
177: out.write(buffer, 0, length);
178: }
179:
180: fis.close();
181: out.close();
182:
183: return null;
184: } else {
185: // show index
186: if (!propFile.exists()) {
187: // build it
188: propFile.getParentFile().mkdirs();
189:
190: FileBrowserPatchHandler fbph = new FileBrowserPatchHandler(
191: baseWorkingDir);
192: FileData patchFile = libresourceSycnhronizerService
193: .getPatch(uri, fromTicket, toTicket);
194: fbph.exportAttachementWithProperties(patchFile
195: .getInputStream());
196: }
197:
198: // load properties
199: Properties props = new Properties();
200: FileInputStream fis = new FileInputStream(propFile);
201: props.load(fis);
202: fis.close();
203:
204: ArrayList pathList = new ArrayList();
205: pathList.addAll(props.keySet());
206:
207: Object[] files = pathList.toArray();
208: Arrays.sort(files);
209:
210: request.setAttribute("fromTicket", Long
211: .toString(fromTicket));
212: request.setAttribute("toTicket", Long
213: .toString(toTicket));
214: request.setAttribute("uri", uri.getPath());
215: request
216: .setAttribute("lastTickets",
217: compressedPatchList);
218:
219: // TODO add expand parameter
220: //String content = printTreeAsHTML(toTree(files));
221: //request.setAttribute("content", content);
222: request.setAttribute("files", files);
223: }
224: } else if ("viewPatch".equals(request.getParameter("view"))) {
225: // View patch online
226: long fromTicket = Long.parseLong(request
227: .getParameter("from"));
228: long toTicket = Long.parseLong(request.getParameter("to"));
229:
230: FileData patch = libresourceSycnhronizerService.getPatch(
231: uri, fromTicket, toTicket);
232: File temp = File.createTempFile("viewpatch", ".xml", Config
233: .getInstance(null).getLsWebBuffer());
234: InputStream is = patch.getInputStream();
235: FileOutputStream os = new FileOutputStream(temp);
236: int readCount = -1;
237: byte[] buffer = new byte[1000000];
238:
239: while ((readCount = is.read(buffer)) > 0) {
240: os.write(buffer, 0, readCount);
241: }
242:
243: os.close();
244:
245: File workingDir = FileUtils.createTmpDir();
246: File cmds = new File(workingDir, "cmds");
247: cmds.mkdirs();
248:
249: File attach = new File(workingDir, "attach");
250: attach.mkdirs();
251:
252: OpVectorFsImpl opVector = new OpVectorFsImpl(cmds.getPath());
253: PatchFile patchFile = new PatchFile(temp.getAbsolutePath());
254: patchFile.buildOpVector(opVector, attach.getPath(), null);
255:
256: ListIterator commands = opVector.getCommands();
257: StringBuffer b = new StringBuffer();
258:
259: while (commands.hasNext()) {
260: Command cmd = (Command) commands.next();
261: b.append(cmd.toString() + "\n");
262:
263: if (cmd instanceof DelBlock) {
264: DelBlock delBlock = (DelBlock) cmd;
265: Collection oldContent = delBlock.getOldContent();
266:
267: for (Iterator i = oldContent.iterator(); i
268: .hasNext();) {
269: b.append(" -- " + (String) i.next() + "\n");
270: }
271: }
272:
273: if (cmd instanceof AddBlock) {
274: AddBlock addBlock = (AddBlock) cmd;
275: Collection oldContent = addBlock.getContent();
276:
277: for (Iterator i = oldContent.iterator(); i
278: .hasNext();) {
279: b.append(" ++ " + (String) i.next() + "\n");
280: }
281: }
282:
283: b.append("\n\n");
284: }
285:
286: request.setAttribute("from", request.getParameter("from"));
287: request.setAttribute("to", request.getParameter("to"));
288: request.setAttribute("patchVerbose", b.toString());
289: }
290:
291: if (request.getParameter("noaction") != null) {
292: return "/pages/modules/so6/viewSimpleSynchronizer.jsp";
293: }
294:
295: return "/pages/modules/so6/viewSynchronizer.jsp";
296: }
297: }
|