/** * Copyright (c) 2007 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 - Initial API and implementation */ package org.eclipse.emf.ecore.resource.impl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; import org.eclipse.emf.common.archive.ArchiveURLConnection; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.URIConverter; public class ArchiveURIHandlerImpl extends URIHandlerImpl { /** * Creates an instance. */ public ArchiveURIHandlerImpl() { super(); } @Override public boolean canHandle(URI uri) { return "archive".equals(uri.scheme()); } @Override public OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException { return createArchive(uri, options).getOutputStream(); } @Override public InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException { return createArchive(uri, options).getInputStream(); } @Override public void delete(URI uri, Map<?, ?> options) throws IOException { createArchive(uri, options).delete(); } @Override public boolean exists(URI uri, Map<?, ?> options) { try { InputStream inputStream = createInputStream(uri, options); inputStream.close(); return true; } catch (IOException exception) { return false; } } @Override public Map<String, ?> getAttributes(URI uri, Map<?, ?> options) { return createArchive(uri, options).getAttributes(); } @Override public void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException { createArchive(uri, options).setAttributes(attributes); } /** * A specialized class for reading from an archive. */ protected class Archive extends ArchiveURLConnection { protected Map<?, ?> options; protected ZipEntry zipEntry; public Archive(URI uri, Map<?, ?> options) { super(uri.toString()); this.options = options; } @Override protected boolean emulateArchiveScheme() { return false; } @Override protected boolean useZipFile() { return true; } @Override protected InputStream createInputStream(String nestedURL) throws IOException { return getURIConverter(options).createInputStream(URI.createURI(nestedURL), options); } @Override protected OutputStream createOutputStream(String nestedURL) throws IOException { return getURIConverter(options).createOutputStream(URI.createURI(nestedURL), options); } @Override protected InputStream yield(ZipEntry zipEntry, InputStream inputStream) throws IOException { this.zipEntry = zipEntry; Map<Object, Object> response = getResponse(options); if (response != null) { response.put(URIConverter.RESPONSE_TIME_STAMP_PROPERTY, zipEntry.getTime()); } return super.yield(zipEntry, inputStream); } @Override protected OutputStream yield(ZipEntry zipEntry, OutputStream outputStream) throws IOException { this.zipEntry = zipEntry; Map<Object, Object> response = getResponse(options); if (response != null) { response.put(URIConverter.RESPONSE_TIME_STAMP_PROPERTY, zipEntry.getTime()); } return super.yield(zipEntry, outputStream); } public Map<String, ?> getAttributes() { Map<String, Object> result = new HashMap<String, Object>(); try { Set<String> requestedAttributes = getRequestedAttributes(options); if (requestedAttributes == null || requestedAttributes.contains(URIConverter.ATTRIBUTE_READ_ONLY)) { Set<String> requestedSubAttributes = new HashSet<String>(); requestedSubAttributes.add(URIConverter.ATTRIBUTE_READ_ONLY); Map<Object, Object> subOptions = new ExtensibleURIConverterImpl.OptionsMap(URIConverter.OPTION_REQUESTED_ATTRIBUTES, requestedSubAttributes, options); result.putAll(getURIConverter(subOptions).getAttributes(URI.createURI(getNestedURL()), subOptions)); } InputStream inputStream = null; if (requestedAttributes == null || requestedAttributes.contains(URIConverter.ATTRIBUTE_DIRECTORY)) { inputStream = getInputStream(); inputStream.close(); result.put(URIConverter.ATTRIBUTE_DIRECTORY, zipEntry.isDirectory()); } if (requestedAttributes == null || requestedAttributes.contains(URIConverter.ATTRIBUTE_LENGTH)) { if (inputStream == null) { inputStream = getInputStream(); inputStream.close(); } result.put(URIConverter.ATTRIBUTE_LENGTH, zipEntry.getSize()); } if (requestedAttributes == null || requestedAttributes.contains(URIConverter.ATTRIBUTE_TIME_STAMP)) { if (inputStream == null) { inputStream = getInputStream(); inputStream.close(); } result.put(URIConverter.ATTRIBUTE_TIME_STAMP, zipEntry.getTime()); } } catch (IOException exception) { // Ignore exceptions. } return result; } public void setAttributes(Map<String, ?> attributes) throws IOException { Long timeStamp = (Long)attributes.get(URIConverter.ATTRIBUTE_TIME_STAMP); if (timeStamp != null) { setTimeStamp(timeStamp); } } } protected Archive createArchive(URI uri, Map<?, ?> options) { return new Archive(uri, options); } }