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.File;
027: import java.io.FileInputStream;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.util.List;
031: import java.util.zip.ZipEntry;
032: import java.util.zip.ZipInputStream;
033: import jeeves.exceptions.BadFormatEx;
034: import jeeves.utils.Xml;
035: import org.jdom.Element;
036:
037: import static org.fao.geonet.kernel.mef.MEFConstants.*;
038:
039: //=============================================================================
040:
041: public class Visitor {
042: //--------------------------------------------------------------------------
043: //---
044: //--- API methods
045: //---
046: //--------------------------------------------------------------------------
047:
048: public static void visit(File mefFile, MEFVisitor v)
049: throws Exception {
050: Element info = handleXml(mefFile, v);
051: handleBin(mefFile, v, info);
052: }
053:
054: //--------------------------------------------------------------------------
055:
056: private static Element handleXml(File mefFile, MEFVisitor v)
057: throws Exception {
058: ZipInputStream zis = new ZipInputStream(new FileInputStream(
059: mefFile));
060: InputStreamBridge isb = new InputStreamBridge(zis);
061:
062: ZipEntry entry;
063:
064: Element md = null;
065: Element info = null;
066:
067: try {
068: while ((entry = zis.getNextEntry()) != null) {
069: String name = entry.getName();
070:
071: if (name.equals(FILE_METADATA))
072: md = Xml.loadStream(isb);
073:
074: else if (name.equals(FILE_INFO))
075: info = Xml.loadStream(isb);
076:
077: zis.closeEntry();
078: }
079: } finally {
080: safeClose(zis);
081: }
082:
083: if (md == null)
084: throw new BadFormatEx("Missing metadata file : "
085: + FILE_METADATA);
086:
087: if (info == null)
088: throw new BadFormatEx("Missing info file : " + FILE_INFO);
089:
090: v.handleMetadata(md);
091: v.handleInfo(info);
092:
093: return info;
094: }
095:
096: //--------------------------------------------------------------------------
097:
098: private static void handleBin(File mefFile, MEFVisitor v,
099: Element info) throws Exception {
100: ZipInputStream zis = new ZipInputStream(new FileInputStream(
101: mefFile));
102: InputStreamBridge isb = new InputStreamBridge(zis);
103:
104: List pubFiles = info.getChild("public").getChildren();
105: List prvFiles = info.getChild("private").getChildren();
106:
107: ZipEntry entry;
108:
109: try {
110: while ((entry = zis.getNextEntry()) != null) {
111: String fullName = entry.getName();
112: String simpleName = new File(fullName).getName();
113:
114: if (fullName.equals(DIR_PUBLIC)
115: || fullName.equals(DIR_PRIVATE))
116: continue;
117:
118: if (fullName.startsWith(DIR_PUBLIC))
119: v.handlePublicFile(simpleName, getChangeDate(
120: pubFiles, simpleName), isb);
121:
122: else if (fullName.startsWith(DIR_PRIVATE))
123: v.handlePrivateFile(simpleName, getChangeDate(
124: prvFiles, simpleName), isb);
125:
126: zis.closeEntry();
127: }
128: } finally {
129: safeClose(zis);
130: }
131: }
132:
133: //--------------------------------------------------------------------------
134:
135: private static String getChangeDate(List files, String fileName)
136: throws Exception {
137: for (Object f : files) {
138: Element file = (Element) f;
139: String name = file.getAttributeValue("name");
140: String date = file.getAttributeValue("changeDate");
141:
142: if (name.equals(fileName))
143: return date;
144: }
145:
146: throw new Exception("File not found in info.xml : " + fileName);
147: }
148:
149: //--------------------------------------------------------------------------
150:
151: private static void safeClose(ZipInputStream zis) {
152: try {
153: zis.close();
154: } catch (IOException e) {
155: e.printStackTrace();
156: }
157: }
158: }
159:
160: //=============================================================================
161:
162: class InputStreamBridge extends InputStream {
163: //--------------------------------------------------------------------------
164: //---
165: //--- Constructor
166: //---
167: //--------------------------------------------------------------------------
168:
169: public InputStreamBridge(InputStream is) {
170: this .is = is;
171: }
172:
173: //--------------------------------------------------------------------------
174: //---
175: //--- Bridging methods
176: //---
177: //--------------------------------------------------------------------------
178:
179: public int read() throws IOException {
180: return is.read();
181: }
182:
183: public int available() throws IOException {
184: return is.available();
185: }
186:
187: //--- this *must* be empty to work with zip files
188: public void close() throws IOException {
189: }
190:
191: public synchronized void mark(int readlimit) {
192: is.mark(readlimit);
193: }
194:
195: public synchronized void reset() throws IOException {
196: is.reset();
197: }
198:
199: public boolean markSupported() {
200: return is.markSupported();
201: }
202:
203: //--------------------------------------------------------------------------
204: //---
205: //--- Variables
206: //---
207: //--------------------------------------------------------------------------
208:
209: private InputStream is;
210: }
211:
212: //=============================================================================
|