001: //=============================================================================
002: //=== Copyright (C) 2001-2007 Food and Agriculture Organization of the
003: //=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
004: //=== and United Nations Environment Programme (UNEP)
005: //===
006: //=== This program is free software; you can redistribute it and/or modify
007: //=== it under the terms of the GNU General Public License as published by
008: //=== the Free Software Foundation; either version 2 of the License, or (at
009: //=== your option) any later version.
010: //===
011: //=== This program is distributed in the hope that it will be useful, but
012: //=== WITHOUT ANY WARRANTY; without even the implied warranty of
013: //=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: //=== General Public License for more details.
015: //===
016: //=== You should have received a copy of the GNU General Public License
017: //=== along with this program; if not, write to the Free Software
018: //=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
019: //===
020: //=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
021: //=== Rome - Italy. email: geonetwork@osgeo.org
022: //==============================================================================
023:
024: package org.fao.geonet.kernel.mef;
025:
026: import java.io.ByteArrayInputStream;
027: import java.io.File;
028: import java.io.FileFilter;
029: import java.io.FileInputStream;
030: import java.io.FileOutputStream;
031: import java.io.IOException;
032: import java.io.InputStream;
033: import java.sql.SQLException;
034: import java.util.ArrayList;
035: import java.util.HashMap;
036: import java.util.List;
037: import java.util.Set;
038: import java.util.zip.ZipEntry;
039: import java.util.zip.ZipOutputStream;
040: import jeeves.resources.dbms.Dbms;
041: import jeeves.server.context.ServiceContext;
042: import jeeves.utils.BinaryFile;
043: import jeeves.utils.Xml;
044: import org.fao.geonet.GeonetContext;
045: import org.fao.geonet.constants.Geonet;
046: import org.fao.geonet.exceptions.MetadataNotFoundEx;
047: import org.fao.geonet.kernel.AccessManager;
048: import org.fao.geonet.kernel.mef.MEFLib.Format;
049: import org.fao.geonet.lib.Lib;
050: import org.fao.geonet.util.ISODate;
051: import org.jdom.Document;
052: import org.jdom.Element;
053:
054: import static org.fao.geonet.kernel.mef.MEFConstants.*;
055:
056: //=============================================================================
057:
058: class Exporter {
059: //--------------------------------------------------------------------------
060: //---
061: //--- API methods
062: //---
063: //--------------------------------------------------------------------------
064:
065: public static String doExport(ServiceContext context, String uuid,
066: Format format, boolean skipUUID) throws Exception {
067: Dbms dbms = (Dbms) context.getResourceManager().open(
068: Geonet.Res.MAIN_DB);
069:
070: Element record = retrieveMetadata(dbms, uuid);
071:
072: String id = record.getChildText("id");
073: String data = record.getChildText("data");
074: String isTemp = record.getChildText("istemplate");
075:
076: if (!"y".equals(isTemp) && !"n".equals(isTemp))
077: throw new Exception("Cannot export sub template");
078:
079: File file = File.createTempFile("mef-", ".mef");
080: String pubDir = Lib.resource.getDir(context, "public", id);
081: String priDir = Lib.resource.getDir(context, "private", id);
082:
083: FileOutputStream fos = new FileOutputStream(file);
084: ZipOutputStream zos = new ZipOutputStream(fos);
085:
086: //--- create folders
087:
088: createDir(zos, DIR_PUBLIC);
089: createDir(zos, DIR_PRIVATE);
090:
091: //--- save metadata
092:
093: if (!data.startsWith("<?xml"))
094: data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"
095: + data;
096:
097: byte[] binData = data.getBytes("UTF-8");
098:
099: addFile(zos, FILE_METADATA, new ByteArrayInputStream(binData));
100:
101: //--- save info file
102:
103: binData = buildInfoFile(context, record, format, pubDir,
104: priDir, skipUUID).getBytes("UTF-8");
105:
106: addFile(zos, FILE_INFO, new ByteArrayInputStream(binData));
107:
108: //--- save thumbnails and maps
109:
110: if (format == Format.PARTIAL || format == Format.FULL)
111: savePublic(zos, pubDir);
112:
113: if (format == Format.FULL)
114: savePrivate(zos, priDir);
115:
116: //--- cleanup and exit
117:
118: zos.close();
119:
120: return file.getAbsolutePath();
121: }
122:
123: //--------------------------------------------------------------------------
124: //---
125: //--- Private methods : zip handling
126: //---
127: //--------------------------------------------------------------------------
128:
129: private static Element retrieveMetadata(Dbms dbms, String uuid)
130: throws SQLException, MetadataNotFoundEx {
131: List list = dbms.select("SELECT * FROM Metadata WHERE uuid=?",
132: uuid).getChildren();
133:
134: if (list.size() == 0)
135: throw new MetadataNotFoundEx("uuid=" + uuid);
136:
137: return (Element) list.get(0);
138: }
139:
140: //--------------------------------------------------------------------------
141:
142: private static void createDir(ZipOutputStream zos, String name)
143: throws IOException {
144: ZipEntry entry = new ZipEntry(name);
145: zos.putNextEntry(entry);
146: zos.closeEntry();
147: }
148:
149: //--------------------------------------------------------------------------
150:
151: private static void addFile(ZipOutputStream zos, String name,
152: InputStream is) throws IOException {
153: ZipEntry entry = new ZipEntry(name);
154: zos.putNextEntry(entry);
155: BinaryFile.copy(is, zos, true, false);
156: zos.closeEntry();
157: }
158:
159: //--------------------------------------------------------------------------
160: //---
161: //--- Private methods : thumbnails and maps saving
162: //---
163: //--------------------------------------------------------------------------
164:
165: private static void savePublic(ZipOutputStream zos, String dir)
166: throws IOException {
167: File[] files = new File(dir).listFiles(filter);
168:
169: if (files != null)
170: for (File file : files)
171: addFile(zos, DIR_PUBLIC + file.getName(),
172: new FileInputStream(file));
173: }
174:
175: //--------------------------------------------------------------------------
176:
177: private static void savePrivate(ZipOutputStream zos, String dir)
178: throws IOException {
179: File[] files = new File(dir).listFiles(filter);
180:
181: if (files != null)
182: for (File file : files)
183: addFile(zos, DIR_PRIVATE + file.getName(),
184: new FileInputStream(file));
185: }
186:
187: //--------------------------------------------------------------------------
188: //---
189: //--- Private methods : info.xml building
190: //---
191: //--------------------------------------------------------------------------
192:
193: private static String buildInfoFile(ServiceContext context,
194: Element md, Format format, String pubDir, String priDir,
195: boolean skipUUID) throws Exception {
196: Dbms dbms = (Dbms) context.getResourceManager().open(
197: Geonet.Res.MAIN_DB);
198:
199: Element info = new Element("info");
200: info.setAttribute("version", VERSION);
201:
202: info
203: .addContent(buildInfoGeneral(md, format, skipUUID,
204: context));
205: info.addContent(buildInfoCategories(dbms, md));
206: info.addContent(buildInfoPrivileges(context, md));
207:
208: info.addContent(buildInfoFiles("public", pubDir));
209: info.addContent(buildInfoFiles("private", priDir));
210:
211: return Xml.getString(new Document(info));
212: }
213:
214: //--------------------------------------------------------------------------
215:
216: private static Element buildInfoGeneral(Element md, Format format,
217: boolean skipUUID, ServiceContext context) {
218: String id = md.getChildText("id");
219: String uuid = md.getChildText("uuid");
220: String schema = md.getChildText("schemaid");
221: String isTemplate = md.getChildText("istemplate").equals("y") ? "true"
222: : "false";
223: String createDate = md.getChildText("createdate");
224: String changeDate = md.getChildText("changedate");
225: String siteId = md.getChildText("source");
226: String rating = md.getChildText("rating");
227: String popularity = md.getChildText("popularity");
228:
229: Element general = new Element("general").addContent(
230: new Element("createDate").setText(createDate))
231: .addContent(
232: new Element("changeDate").setText(changeDate))
233: .addContent(new Element("schema").setText(schema))
234: .addContent(
235: new Element("isTemplate").setText(isTemplate))
236: .addContent(new Element("localId").setText(id))
237: .addContent(
238: new Element("format")
239: .setText(format.toString()))
240: .addContent(new Element("rating").setText(rating))
241: .addContent(
242: new Element("popularity").setText(popularity));
243:
244: if (!skipUUID) {
245: GeonetContext gc = (GeonetContext) context
246: .getHandlerContext(Geonet.CONTEXT_NAME);
247:
248: general.addContent(new Element("uuid").setText(uuid));
249: general.addContent(new Element("siteId").setText(siteId));
250: general.addContent(new Element("siteName").setText(gc
251: .getSiteName()));
252: }
253:
254: return general;
255: }
256:
257: //--------------------------------------------------------------------------
258:
259: private static Element buildInfoCategories(Dbms dbms, Element md)
260: throws SQLException {
261: Element categ = new Element("categories");
262:
263: String id = md.getChildText("id");
264: String query = "SELECT name FROM MetadataCateg, Categories "
265: + "WHERE categoryId = id AND metadataId = " + id;
266:
267: List list = dbms.select(query).getChildren();
268:
269: for (int i = 0; i < list.size(); i++) {
270: Element record = (Element) list.get(i);
271: String name = record.getChildText("name");
272:
273: Element cat = new Element("category");
274: cat.setAttribute("name", name);
275:
276: categ.addContent(cat);
277: }
278:
279: return categ;
280: }
281:
282: //--------------------------------------------------------------------------
283:
284: private static Element buildInfoPrivileges(ServiceContext context,
285: Element md) throws Exception {
286: Dbms dbms = (Dbms) context.getResourceManager().open(
287: Geonet.Res.MAIN_DB);
288:
289: String id = md.getChildText("id");
290: String query = "SELECT Groups.id as grpid, Groups.name as grpName, Operations.name as operName "
291: + "FROM OperationAllowed, Groups, Operations "
292: + "WHERE groupId = Groups.id "
293: + " AND operationId = Operations.id "
294: + " AND metadataId = " + id;
295:
296: HashMap<String, ArrayList<String>> hmPriv = new HashMap<String, ArrayList<String>>();
297:
298: //--- retrieve accessible groups
299:
300: GeonetContext gc = (GeonetContext) context
301: .getHandlerContext(Geonet.CONTEXT_NAME);
302: AccessManager am = gc.getAccessManager();
303:
304: Set<String> userGroups = am.getUserGroups(dbms, context
305: .getUserSession(), context.getIpAddress());
306:
307: //--- scan query result to collect info
308:
309: List list = dbms.select(query).getChildren();
310:
311: for (int i = 0; i < list.size(); i++) {
312: Element record = (Element) list.get(i);
313: String grpId = record.getChildText("grpid");
314: String grpName = record.getChildText("grpname");
315: String operName = record.getChildText("opername");
316:
317: if (!userGroups.contains(grpId))
318: continue;
319:
320: ArrayList<String> al = hmPriv.get(grpName);
321:
322: if (al == null) {
323: al = new ArrayList<String>();
324: hmPriv.put(grpName, al);
325: }
326:
327: al.add(operName);
328: }
329:
330: //--- generate elements
331:
332: Element privil = new Element("privileges");
333:
334: for (String grpName : hmPriv.keySet()) {
335: Element group = new Element("group");
336: group.setAttribute("name", grpName);
337: privil.addContent(group);
338:
339: for (String operName : hmPriv.get(grpName)) {
340: Element oper = new Element("operation");
341: oper.setAttribute("name", operName);
342:
343: group.addContent(oper);
344: }
345: }
346:
347: return privil;
348: }
349:
350: //--------------------------------------------------------------------------
351:
352: private static Element buildInfoFiles(String name, String dir) {
353: Element root = new Element(name);
354:
355: File[] files = new File(dir).listFiles(filter);
356:
357: if (files != null)
358: for (File file : files) {
359: String date = new ISODate(file.lastModified())
360: .toString();
361:
362: Element el = new Element("file");
363: el.setAttribute("name", file.getName());
364: el.setAttribute("changeDate", date);
365:
366: root.addContent(el);
367: }
368:
369: return root;
370: }
371:
372: //--------------------------------------------------------------------------
373: //---
374: //--- Variables
375: //---
376: //--------------------------------------------------------------------------
377:
378: private static FileFilter filter = new FileFilter() {
379: public boolean accept(File pathname) {
380: if (pathname.getName().equals(".svn"))
381: return false;
382:
383: return true;
384: }
385: };
386: }
387:
388: //=============================================================================
|