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.so6.core.exec;
034:
035: import org.libresource.so6.core.WsConnection;
036: import org.libresource.so6.core.client.ClientI;
037: import org.libresource.so6.core.engine.DBType;
038: import org.libresource.so6.core.engine.PatchFile;
039: import org.libresource.so6.core.engine.util.InfoPatchHandler;
040:
041: import java.io.File;
042: import java.io.FileInputStream;
043: import java.io.FileOutputStream;
044:
045: import java.lang.reflect.Constructor;
046:
047: import java.util.Properties;
048:
049: import javax.xml.parsers.SAXParser;
050: import javax.xml.parsers.SAXParserFactory;
051:
052: /**
053: * The <code>AnonymousAccess</code> class is used to download a remote project
054: *
055: * @author Smack
056: * @version 1.0, 26/05/04
057: * @since JDK1.4
058: */
059: public class AnonymousAccess {
060: public static final String LAST_TICKET = "anonymous.last.ticket";
061: public static final String DBTYPE = "anonymous.dbtype";
062: private Properties props;
063: private String propsFilePath;
064: private String dbTypeFilePath;
065: private long maxTicket;
066:
067: /**
068: * Instantiate a Download process with a ticket limit
069: *
070: * @param downloadPropPath
071: * Path of the property file of the AnonymousAccess
072: * @param maxTicket
073: * Ticket limit
074: * @throws Exception
075: */
076: public AnonymousAccess(String downloadFilePropPath, long maxTicket)
077: throws Exception {
078: this .maxTicket = maxTicket;
079: this .propsFilePath = downloadFilePropPath;
080: dbTypeFilePath = new File(downloadFilePropPath).getParent()
081: + File.separator + DBTYPE;
082: props = new Properties();
083:
084: FileInputStream fis = new FileInputStream(downloadFilePropPath);
085: props.load(fis);
086: fis.close();
087: }
088:
089: /**
090: * Instantiate a Download process without ticket limit.
091: *
092: * @param downloadFilePropPath
093: * Path of the property file of the AnonymousAccess
094: * @throws Exception
095: */
096: public AnonymousAccess(String downloadFilePropPath)
097: throws Exception {
098: this (downloadFilePropPath, -1);
099: }
100:
101: private String getNextPatch(ClientI client) throws Exception {
102: if (maxTicket > 0) {
103: long[][] patchList = client.listPatch();
104:
105: for (int i = 0; i < patchList.length; i++) {
106: if ((patchList[i][0] == (getLastTicket() + 1))
107: && (patchList[i][1] == maxTicket)) {
108: return client.getPatch(getLastTicket() + 1,
109: maxTicket);
110: }
111: }
112:
113: for (int i = 0; i < patchList.length; i++) {
114: if ((patchList[i][0] == (getLastTicket() + 1))
115: && (patchList[i][1] < maxTicket)) {
116: return client.getPatch(getLastTicket() + 1,
117: patchList[i][1]);
118: }
119: }
120: }
121:
122: return client.getPatch(getLastTicket() + 1);
123: }
124:
125: /**
126: * Execute the download process
127: *
128: * @throws Exception
129: */
130: public void execute() throws Exception {
131: Constructor construct = Class.forName(
132: props.getProperty(WsConnection.SYNC_CLIENT_NAME))
133: .getConstructor(new Class[] { Properties.class });
134: ClientI client = ((ClientI) construct
135: .newInstance(new Object[] { props }));
136: long lastQueueTicket = client.getLastTicket();
137:
138: if (maxTicket > 0) {
139: lastQueueTicket = maxTicket;
140: }
141:
142: //
143: String basePath = props.getProperty(WsConnection.PATH);
144: DBType dbType = new DBType(dbTypeFilePath, "");
145: SAXParserFactory factory = SAXParserFactory.newInstance();
146: SAXParser saxParser = factory.newSAXParser();
147: InfoPatchHandler infoPatch = new InfoPatchHandler();
148:
149: while (getLastTicket() < lastQueueTicket) {
150: String patchPath = getNextPatch(client);
151: saxParser.parse(new File(patchPath), infoPatch);
152:
153: PatchFile pf = new PatchFile(patchPath);
154: pf.patch(basePath, dbType);
155: System.out.println("Updated to " + infoPatch.getToTicket());
156: setLastTicket(infoPatch.getToTicket());
157: }
158: }
159:
160: private long getLastTicket() {
161: return Long.parseLong(props.getProperty(LAST_TICKET, "0"));
162: }
163:
164: private void setLastTicket(long lastTicket) throws Exception {
165: props.setProperty(LAST_TICKET, Long.toString(lastTicket));
166:
167: FileOutputStream fos = new FileOutputStream(propsFilePath);
168: props.store(fos, "");
169: fos.close();
170: }
171:
172: /**
173: * Instantiate and execute the AnonymousAccess process
174: *
175: * @param args
176: * <ul>
177: * <li>Path of the donwload property file</li>
178: * <li>ticket boundary (should be avoided when we want to reach
179: * the last state)</li>
180: * </ul>
181: * <p>
182: * The property file should look like this
183: *
184: * <pre>
185: *
186: * so6.clienti.name=org.libresource.so6.client.soap.ClientISoapImpl
187: * so6.path=/home/seb/so6
188: *
189: * and all the properties needed to instanciate the ClientI...
190: * (so6.soap.url.endpoint=http\://courgette.loria.fr\:80/ls-so6/services/so6)
191: * (so6.soap.synchronizer.uri=/projects/So6/Sources)
192: *
193: * </pre>
194: *
195: * @throws Exception
196: */
197: public static void main(String[] args) throws Exception {
198: if (args.length < 1) {
199: System.err.println("Usage: downloadFilePath (lastTicket)");
200: System.err
201: .println(" (1) downloadFilePath: path of the file needed to instantiate the client");
202: System.err
203: .println(" (2) lastTicket: if you want to get an older state");
204: } else {
205: AnonymousAccess co = null;
206:
207: if (args.length == 1) {
208: co = new AnonymousAccess(args[0]);
209: }
210:
211: if (args.length == 2) {
212: co = new AnonymousAccess(args[0], Long
213: .parseLong(args[1]));
214: }
215:
216: if (co != null) {
217: co.execute();
218: }
219: }
220: }
221: }
|