View Javadoc

1   /*
2    * Copyright (c) 2005 Regents of the University of California (Regents). Created
3    * by TELS, Graduate School of Education, University of California at Berkeley.
4    *
5    * This software is distributed under the GNU Lesser General Public License, v2.
6    *
7    * Permission is hereby granted, without written agreement and without license
8    * or royalty fees, to use, copy, modify, and distribute this software and its
9    * documentation for any purpose, provided that the above copyright notice and
10   * the following two paragraphs appear in all copies of this software.
11   *
12   * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
13   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
14   * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
15   * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
16   * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17   *
18   * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
19   * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
20   * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
21   * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22   */
23  package net.sf.sail.core.curnit;
24  
25  import java.beans.XMLDecoder;
26  import java.io.File;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.net.URL;
30  import java.util.Collections;
31  import java.util.Enumeration;
32  import java.util.HashMap;
33  import java.util.Map;
34  import java.util.Properties;
35  import java.util.jar.Attributes;
36  import java.util.jar.JarEntry;
37  import java.util.jar.JarFile;
38  import java.util.jar.Manifest;
39  
40  import net.sf.sail.common.apps.PreviewCurnit;
41  import net.sf.sail.core.beans.Pod;
42  import net.sf.sail.core.beans.assembly.PodRegistry;
43  import net.sf.sail.core.util.MarshallUtils;
44  import net.sf.sail.core.uuid.PodUuid;
45  
46  /**
47   * Represents a Curnit archive file. Provides methods for loading and rebuilding
48   * the Curnit.
49   * 
50   * @see net.sf.sail.test.beans.Curnit
51   * @author turadg
52   * AUDIT07-
53   */
54  public class CurnitFile extends JarFile {
55  
56  	/**
57  	 * Registry of pods to use for this curnit file
58  	 */
59  	private static final PodRegistry REGISTRY = PodRegistry
60  			.getDefaultRegistry();
61  	public static final String WITHINCURNIT_PROTOCOL = "withincurnit:";
62  	public static final String WITHINCURNIT_BASEPATH = "withincurnit";
63  
64  	public static final Attributes.Name CURNIT_TITLE_ATTR = new Attributes.Name(
65  			"Curnit-Title");
66  
67  	public static final Attributes.Name CURNIT_FORMAT_ATTR = new Attributes.Name(
68  			"Curnit-Format");
69  
70  	public static final Attributes.Name MAIN_CLASS_ATTR = new Attributes.Name(
71  			"Main-Class");
72  
73  	public static final Class<PreviewCurnit> MAIN_CLASS = PreviewCurnit.class;
74  
75  	Curnit curnitLoaded;
76  
77  	public static final String CURNITXML_NAME = "curnit.xml";
78  
79  	public static final String PODSREFERENCED_NAME = "podsReferenced.properties";
80  
81  	private String _title;
82  
83  	private Map<PodUuid, String> referencedPodsMap = new HashMap<PodUuid, String>();
84  
85  	public CurnitFile(File file) throws IOException {
86  		super(file);
87  		net.sf.sail.core.net.podar.Handler.registerProtocol();
88  		net.sf.sail.core.net.curnitarchive.Handler.registerProtocol();
89  	}
90  
91  	public String getCurnitTitle() throws IOException {
92  		if (_title == null) {
93  			Manifest mf = getManifest();
94  			if (mf == null)
95  				throw new IOException("no manifest");
96  			Attributes attrs = mf.getMainAttributes();
97  			_title = (String) attrs.get(CURNIT_TITLE_ATTR);
98  		}
99  
100 		return _title;
101 	}
102 
103 	public Curnit getCurnit() throws IOException {
104 		if (curnitLoaded != null)
105 			return curnitLoaded;
106 
107 		InputStream in;
108 
109 		JarEntry curnitEntry = getJarEntry(CURNITXML_NAME);
110 		in = getInputStream(curnitEntry);
111 		Curnit curnit = MarshallUtils.readCurnit(in);
112 
113 		loadPods(curnit);
114 
115 		return curnit;
116 	}
117 
118 	/**
119 	 * Load the content of the pods in the curnit. Linking the url of its podarchive(resources are stored) to the podid.
120 	 * 
121 	 * @param curnit
122 	 * @throws IOException
123 	 */
124 	private void loadPods(Curnit curnit) throws IOException {
125 		loadReferencedPodMap();
126 
127 		for (Map.Entry<PodUuid, String> entry : referencedPodsMap.entrySet()) {
128 			PodUuid podId = entry.getKey();
129 			String urlString = entry.getValue();
130 			// load pod's archive
131 			if (urlString.length() > 0) {
132 				URL podurl;
133 				if (urlString.startsWith(WITHINCURNIT_PROTOCOL)) {
134 					// pod archive is stored in curnit archive
135 					int offset = WITHINCURNIT_PROTOCOL.length();
136 					String path = urlString.substring(offset);
137 					podurl = CurnitArchiveResolver.withinCurnitArchive(curnit
138 							.getCurnitId(), path);
139 				} else {
140 					// pod archive is out on the internet
141 					podurl = new URL(urlString);
142 				}
143 				PodArchiveResolver.getSystemResolver().put(podId, podurl);
144 			}
145 
146 			// then load pod's xml and unmarshall
147 			loadPod(podId);
148 		}
149 	}
150 
151 	/**
152 	 * Specifies the pods and its dependecy. Doesn't load in any of the jar files. creates mapping of pods.
153 	 * 
154 	 * @throws IOException
155 	 */
156 	private void loadReferencedPodMap() throws IOException {
157 		InputStream in;
158 		JarEntry depsEntry = getJarEntry(PODSREFERENCED_NAME);
159 		in = getInputStream(depsEntry);
160 		Properties deps = new Properties();
161 		deps.load(in);
162 		Enumeration<?> en = deps.propertyNames();
163 		while (en.hasMoreElements()) {
164 			String podIdStr = (String) en.nextElement();
165 			PodUuid podId = new PodUuid(podIdStr);
166 			String urlString = deps.getProperty(podId.toString());
167 			referencedPodsMap.put(podId, urlString);
168 		}
169 	}
170 
171 	/**
172 	 * @return Returns an unmodifiable version of the referencedPodsMap.
173 	 */
174 	public Map<PodUuid, String> getReferencedPodsMap() {
175 		if (referencedPodsMap == null)
176 			try {
177 				loadReferencedPodMap();
178 			} catch (IOException e) {
179 				// TODO Auto-generated catch block
180 				e.printStackTrace();
181 			}
182 		return Collections.unmodifiableMap(referencedPodsMap);
183 	}
184 
185 	/**
186 	 * Loads the contents of the pod and registers to a map.
187 	 * 
188 	 * @param podId - the podId of the pod to load
189 	 * @throws IOException
190 	 */
191 	private void loadPod(PodUuid podId) throws IOException {
192 		JarEntry podEntry = entryFor(podId);
193 		InputStream in = getInputStream(podEntry);
194 		XMLDecoder dec = new XMLDecoder(in);
195 		dec.setExceptionListener(SAILXMLEncoder.haltingExceptionListener);
196 		Pod pod = (Pod) dec.readObject();
197 		REGISTRY.register(pod);
198 	}
199 
200 	/**
201 	 * Contructs a filename out of the podId
202 	 * 
203 	 * @param podId - podId
204 	 * @return a jar entry 
205 	 */
206 	public static JarEntry entryFor(PodUuid podId) {
207 		String filename = "POD_" + podId + ".xml";
208 		return new JarEntry(filename);
209 	}
210 
211 }