Skip to main content
summaryrefslogtreecommitdiffstats
blob: a5b3a42290c2eaa1d32cbf46eadf2c05eeeeee56 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.commonarchivecore.internal.helpers;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import com.ibm.icu.util.StringTokenizer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy;
import org.eclipse.jst.jee.archive.internal.ArchiveUtil;


/**
 * Helper class used for loading of mof resources contained within an archive; knows how to retrieve
 * an input stream for a given uri
 */
public class ArchiveURIConverterImpl extends URIConverterImpl {
	protected static final String fileProtocol = "file"; //$NON-NLS-1$
	protected static final String platformProtocol = "platform"; //$NON-NLS-1$
	private String inFilepath, outFilepath;

	public ArchiveURIConverterImpl(org.eclipse.jst.j2ee.commonarchivecore.internal.Archive anArchive, String resourcesPath) {
		setArchive(anArchive);
		this.resourcesPath = resourcesPath;
		setInputFilepath(resourcesPath);
		String outpath = resourcesPath;
		if (outpath == null) {
			LoadStrategy l = anArchive.getLoadStrategy();
			if (l != null && l.isDirectory()) {
				try {
					outpath = l.getAbsolutePath();
				} catch (FileNotFoundException ignore) {
					//Ignore
				}
			}
		}
		setOutputFilepath(outpath);
	}

	/** The archive from which resources will be loaded */
	protected org.eclipse.jst.j2ee.commonarchivecore.internal.Archive archive;
	protected String resourcesPath;

	public org.eclipse.jst.j2ee.commonarchivecore.internal.Archive getArchive() {
		return archive;
	}

	@Override
	public InputStream createInputStream(URI uri) throws IOException {
		InputStream in = null;
		if (resourcesPath != null)
			in = makeInputStream(uri);
		if (in != null)
			return in;
		return getArchive().getInputStream(uri.toString());
	}

	public void setArchive(org.eclipse.jst.j2ee.commonarchivecore.internal.Archive newArchive) {
		archive = newArchive;
	}

	/**
	 * Gets the resourcesPath.
	 * 
	 * @return Returns a String
	 */
	public String getResourcesPath() {
		return resourcesPath;
	}

	/**
	 * Sets the resourcesPath.
	 * 
	 * @param resourcesPath
	 *            The resourcesPath to set
	 */
	public void setResourcesPath(String resourcesPath) {
		this.resourcesPath = resourcesPath;
		setInputFilepath(resourcesPath);
		setOutputFilepath(resourcesPath);
	}

	@Override
	public URI normalize(URI uri) {
		return ((URIConverterImpl.URIMap)getURIMap()).getURI(uri);
	}

	/**
	 * The input file path consists of a string of directories or zip files separated by semi-colons
	 * that are searched when an input stream is constructed.
	 * 
	 * @return The file path
	 */
	public String getInputFilepath() {
		return inFilepath;
	}

	/**
	 * @param filepath
	 *            The file path
	 */
	public void setInputFilepath(String filepath) {
		inFilepath = filepath;
	}

	/**
	 * @return The output file path
	 */
	public String getOutputFilepath() {
		return outFilepath;
	}

	/**
	 * The output file path is the path name of a directory to prepend to relative file path names
	 * when an output stream is constructed.
	 * 
	 * @param filepath
	 *            The output file path
	 */
	public void setOutputFilepath(String filepath) {
		outFilepath = filepath;
	}

	/**
	 * Convert the URI to an input stream.
	 * 
	 * @param uri
	 *            The uri
	 */
	public InputStream makeInputStream(URI uri) throws IOException {
		URI converted = uri;

		if ((fileProtocol.equals(converted.scheme()) || converted.scheme() == null) && inFilepath != null) {
			return searchFilePath(converted.toString());
		}
		URL url = createURL(converted.toString());
		URLConnection urlConnection = url.openConnection();
		return urlConnection.getInputStream();
	}

	/**
	 * Search the file path if the file portion of the URL is not absolute (does not begin with "/";
	 * otherwise, attempt to create an input stream for the file.
	 */
	protected InputStream searchFilePath(String filename) throws IOException {
		File file = new File(filename);
		if (file.isAbsolute())
			return new FileInputStream(file);
		StringTokenizer st = new StringTokenizer(inFilepath, ";"); //$NON-NLS-1$
		while (st.hasMoreTokens()) {
			String f = st.nextToken();
			ZipFile zf = null;
			try {
				zf = ArchiveUtil.newZipFile(f);
			} catch (Exception e) {
				//Ignore
			}
			InputStream in = null;
			if (zf != null) {
				in = searchZipFile(zf, filename);
				if (in == null)
					try {
						zf.close();
					} catch (Exception e) {
						//Ignore
					}
			} else {
				in = searchDirectory(f, filename);
			}
			if (in != null)
				return in;
		}
		return null;
	}

	/**
	 * This method determines whether the file with the relative path name of filename exists in the
	 * given directory. If not, it returns null; otherwise, it opens the file up and returns the
	 * input source.
	 * 
	 * @param dir
	 *            java.lang.String
	 * @return java.io.InputSource
	 */
	protected InputStream searchDirectory(String dir, String filename) throws IOException {
		if (dir.equals(".")) //$NON-NLS-1$
			dir = System.getProperty("user.dir"); //$NON-NLS-1$
		File f = new File(dir + System.getProperty("file.separator") + filename.replace('/', File.separatorChar)); //$NON-NLS-1$
		if (!f.exists())
			return null;
		return new FileInputStream(f);
	}

	/**
	 * This method determines whether there is a ZipEntry whose name is filename in the given
	 * ZipFile. If not, it returns null; otherwise, it returns an input source to read from the
	 * ZipEntry.
	 * 
	 * @param zip
	 *            java.util.zip.ZipFile
	 * @return java.io.InputSource
	 */
	protected InputStream searchZipFile(ZipFile zip, String filename) throws IOException {
		ZipEntry entry = zip.getEntry(filename);
		if (entry == null)
			return null;
		return zip.getInputStream(entry);
	}

	/**
	 * Make a URL from the uri; if the attempt fails, attempt to append "file:" to the URI; if the
	 * attempt still fails, attempt to replace the protocol with the file protocol.
	 * 
	 * @param uri
	 *            The string uri
	 */
	public URL createURL(String uri) throws MalformedURLException {
		MalformedURLException m = null;
		if (uri == null)
			return null;
		URL url = null;
		try {
			url = new URL(uri);
		} catch (Exception e) {
			m = (MalformedURLException) e;
		}
		if (url != null)
			return url;
		// Either treat the URI as a filepath (if there are no : or
		// a : in position 1) or replace the given protocol with the
		// file protocol.
		int index = uri.indexOf(":"); //$NON-NLS-1$
		if (index == -1 || index == 1)
			uri = fileProtocol + ":" + uri; //$NON-NLS-1$
		else if (index > 0)
			uri = fileProtocol + ":" + uri.substring(index + 1); //$NON-NLS-1$
		try {
			url = new URL(uri);
		} catch (Exception e) {
			//Ignore
		}
		if (url != null)
			return url;
		else if(m != null)
			throw m;
		else 
			throw new MalformedURLException();
	}

	/**
	 * Convert the URI to an output stream.
	 * 
	 * @param uri
	 *            The uri
	 */
	@Override
	public OutputStream createOutputStream(URI uri) throws IOException {
		URI converted = uri;
		if (platformProtocol.equals(converted.scheme())) {
			URL resolvedURL = resolvePlatform(new URL(converted.toString()));
			if (resolvedURL != null) {
				converted = URI.createFileURI(resolvedURL.getFile());
			}
		}
		if (fileProtocol.equals(converted.scheme()) || converted.scheme() == null) {
			return openFileOutputStream(converted);
		}
		URL url = createURL(converted.toString());
		URLConnection urlConnection = url.openConnection();
		urlConnection.setDoOutput(true);
		return urlConnection.getOutputStream();
	}

	protected URL resolvePlatform(URL url) throws IOException {
		// let WorkbenchURIConverter implement this one.
		return null;
	}

	/**
	 * Open a file output stream for the given uri (the uri has file protocol). If an output file
	 * path is specified and the file name is relative, prepend the output file path to the file
	 * name. Make the directories that contain the file if they do not exist.
	 */
	protected OutputStream openFileOutputStream(URI uri) throws IOException {
		File file = new File(uri.toFileString());
		if (!file.isAbsolute() && outFilepath != null) {
			file = new File(outFilepath + File.separator + uri.toFileString());
		}
		String parent = file.getParent();
		if (parent != null) {
			new File(parent).mkdirs();
		}
		OutputStream outputStream = new FileOutputStream(file);
		return outputStream;
	}
}

Back to the top