blob: 838b46a6744476366bd16d149a122f631ae45337 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 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 Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.j2ee.internal.componentcore;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveTypeDiscriminator;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.jee.archive.internal.ArchiveUtil;
import org.eclipse.wst.common.componentcore.internal.BinaryComponentHelper;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
/**
* @deprecated see {@link JavaEEBinaryComponentHelper}
* @author jasholl
*
*/
public abstract class EnterpriseBinaryComponentHelper extends BinaryComponentHelper {
public static EnterpriseBinaryComponentHelper getHelper(IVirtualComponent aComponent){
EnterpriseBinaryComponentHelper helper = null;
if (JavaEEProjectUtilities.isEJBComponent(aComponent)) {
helper = new EJBBinaryComponentHelper(aComponent);
} else if (JavaEEProjectUtilities.isApplicationClientComponent(aComponent)) {
helper = new AppClientBinaryComponentHelper(aComponent);
} else if (JavaEEProjectUtilities.isJCAComponent(aComponent)) {
helper = new JCABinaryComponentHelper(aComponent);
} else if (JavaEEProjectUtilities.isDynamicWebComponent(aComponent)) {
helper = new WebBinaryComponentHelper(aComponent);
} else {
helper = new UtilityBinaryComponentHelper(aComponent);
}
return helper;
}
IReferenceCountedArchive archive = null;
protected EnterpriseBinaryComponentHelper(IVirtualComponent component) {
super(component);
}
protected ComponentArchiveOptions getArchiveOptions() {
ComponentArchiveOptions options = new ComponentArchiveOptions(getComponent());
options.setIsReadOnly(true);
options.setRendererType(ArchiveOptions.SAX);
options.setUseJavaReflection(false);
return options;
}
protected IReferenceCountedArchive getUniqueArchive() {
try {
return openArchive();
} catch (OpenFailureException e) {
J2EEPlugin.logError(e);
}
return null;
}
public Archive accessArchive() {
IReferenceCountedArchive archive = getArchive();
archive.access();
if(!isPhysicallyOpen(archive)){
physicallyOpen(archive);
}
return archive;
}
protected IReferenceCountedArchive getArchive() {
if (archive == null) {
archive = getUniqueArchive();
}
return archive;
}
protected boolean isArchiveValid() {
if (archive != null) {
return true;
}
Archive anArchive = null;
try {
anArchive = CommonarchiveFactory.eINSTANCE.primOpenArchive(getArchiveOptions(), getArchiveURI());
ArchiveTypeDiscriminator disc = getDiscriminator();
return null == disc || disc.canImport(anArchive);
} catch (Exception e) {
return false;
} finally {
if (anArchive != null) {
anArchive.close();
}
}
}
protected String getArchiveURI() {
java.io.File file = (java.io.File)getComponent().getAdapter(java.io.File.class);
return file.getAbsolutePath();
}
@Override
public void dispose() {
if (archive != null) {
archive.close();
archive = null;
}
}
protected abstract ArchiveTypeDiscriminator getDiscriminator();
protected IReferenceCountedArchive openArchive() throws OpenFailureException {
ArchiveCache cache = ArchiveCache.getInstance();
IReferenceCountedArchive archive = cache.getArchive(getComponent());
if (archive != null) {
archive.access();
return archive;
}
return cache.openArchive(this);
}
boolean gotResource = false;
@Override
public Resource getResource(URI uri) {
Resource resource = null;
if(!isPhysicallyOpen(getArchive())){
resource = getArchive().getResourceSet().getResource(uri, false);
if(resource == null){
physicallyOpen(getArchive());
}
}
if(resource == null){
resource = getArchive().getResourceSet().getResource(uri, true);
}
return resource;
}
public void releaseAccess() {
dispose();
}
private static void unloadArchive(IReferenceCountedArchive archive) {
WorkbenchResourceHelperBase.removeAndUnloadAll(archive.getResourceSet().getResources(), archive.getResourceSet());
archive.getLoadStrategy().setResourceSet(null);
archive.setLoadStrategy(null);
}
private static boolean isPhysicallyOpen(IReferenceCountedArchive archive) {
return ((BinaryZipFileLoadStrategy)archive.getLoadStrategy()).isPhysicallyOpen();
}
private static void physicallyOpen(IReferenceCountedArchive archive) {
try {
((BinaryZipFileLoadStrategy)archive.getLoadStrategy()).physicallyOpen();
} catch (ZipException e) {
J2EEPlugin.logError(e);
} catch (IOException e) {
J2EEPlugin.logError(e);
}
}
protected static void physicallyClose(IReferenceCountedArchive archive) {
((BinaryZipFileLoadStrategy)archive.getLoadStrategy()).physicallyClose();
}
protected void aboutToClose() {
//default is to do nothing
}
protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
//default is to do nothing
}
protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
//default is to do nothing
}
private static class BinaryZipFileLoadStrategy extends ZipFileLoadStrategyImpl {
private boolean physicallyOpen = true;
public BinaryZipFileLoadStrategy(java.io.File file) throws IOException {
super(file);
}
@Override
public void close() {
physicallyOpen = false;
super.close();
}
public boolean isPhysicallyOpen(){
return physicallyOpen;
}
public void physicallyOpen() throws ZipException, IOException{
if(!isPhysicallyOpen()){
physicallyOpen = true;
setZipFile(ArchiveUtil.newZipFile(file));
}
}
public void physicallyClose(){
if(isPhysicallyOpen()){
physicallyOpen = false;
try{
zipFile.close();
}
catch (Throwable t) {
//Ignore
}
}
}
@Override
public InputStream getInputStream(String uri) throws IOException, FileNotFoundException {
final boolean isPhysciallyOpen = isPhysicallyOpen();
Exception caughtException = null;
try {
if (!isPhysciallyOpen) {
physicallyOpen();
}
ZipEntry entry = getZipFile().getEntry(uri);
if (entry == null)
throw new FileNotFoundException(uri);
return new java.io.BufferedInputStream(getZipFile().getInputStream(entry)) {
@Override
public void close() throws IOException {
super.close();
if (!isPhysciallyOpen ) {
physicallyClose();
}
}
};
} catch (FileNotFoundException e) {
caughtException = e;
throw e;
} catch (IllegalStateException zipClosed) {
caughtException = zipClosed;
throw new IOException(zipClosed.toString());
} catch (Exception e) {
caughtException = e;
throw new IOException(e.toString());
} finally {
if (caughtException != null) {
if (!isPhysciallyOpen) {
physicallyClose();
}
}
}
}
}
public static class ArchiveCache {
private static ArchiveCache instance = null;
public static ArchiveCache getInstance() {
if (instance == null) {
instance = new ArchiveCache();
}
return instance;
}
protected Map componentsToArchives = new Hashtable();
public synchronized IReferenceCountedArchive getArchive(IVirtualComponent component) {
IReferenceCountedArchive archive = (IReferenceCountedArchive) componentsToArchives.get(component);
return archive;
}
public synchronized void clearDisconnectedArchivesInEAR(IVirtualComponent earComponent) {
if (componentsToArchives.isEmpty()) {
return;
}
Set liveBinaryComponnts = new HashSet();
IVirtualReference[] refs = earComponent.getReferences();
IVirtualComponent component = null;
for (int i = 0; i < refs.length; i++) {
component = refs[i].getReferencedComponent();
if (component.isBinary()) {
liveBinaryComponnts.add(component);
}
}
clearArchivesInProject(earComponent.getProject(), liveBinaryComponnts);
}
public synchronized void clearAllArchivesInProject(IProject earProject) {
if (componentsToArchives.isEmpty()) {
return;
}
clearArchivesInProject(earProject, null);
}
private void clearArchivesInProject(IProject earProject, Set excludeSet) {
Iterator iterator = componentsToArchives.entrySet().iterator();
IVirtualComponent component = null;
IReferenceCountedArchive archive = null;
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry)iterator.next();
component = (IVirtualComponent) entry.getKey();
if (component.getProject().equals(earProject) && (excludeSet == null || !excludeSet.contains(component))) {
archive = (IReferenceCountedArchive) entry.getValue();
archive.forceClose();
unloadArchive(archive);
iterator.remove();
}
}
}
public synchronized IReferenceCountedArchive openArchive(EnterpriseBinaryComponentHelper helper) throws OpenFailureException {
ArchiveOptions options = helper.getArchiveOptions();
String archiveURI = helper.getArchiveURI();
options.setLoadStrategy(createBinaryLoadStrategy(helper));
Archive anArchive = CommonarchiveFactory.eINSTANCE.primOpenArchive(options, archiveURI);
ArchiveTypeDiscriminator discriminator = helper.getDiscriminator();
if (!discriminator.canImport(anArchive)) {
anArchive.close();
throw new OpenFailureException(discriminator.getUnableToOpenMessage());
}
IReferenceCountedArchive specificArchive = (IReferenceCountedArchive) discriminator.openArchive(anArchive);
specificArchive.setEnterpriseBinaryComponentHelper(helper);
specificArchive.initializeAfterOpen();
specificArchive.access();
componentsToArchives.put(helper.getComponent(), specificArchive);
return specificArchive;
}
}
protected static BinaryZipFileLoadStrategy createBinaryLoadStrategy(EnterpriseBinaryComponentHelper helper) throws OpenFailureException {
String archiveURI = helper.getArchiveURI();
String filename = archiveURI.replace('/', java.io.File.separatorChar);
java.io.File file = new java.io.File(filename);
if (!file.exists()) {
throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.file_not_found_EXC_, (new Object[] { archiveURI, file.getAbsolutePath() })));
}
try {
BinaryZipFileLoadStrategy strategy = new BinaryZipFileLoadStrategy(file);
return strategy;
} catch (IOException ex) {
throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.could_not_open_EXC_, (new Object[] { archiveURI })), ex);
}
}
protected interface IReferenceCountedArchive extends Archive {
/**
* Increases the reference count by one. A call to close will decriment
* the count by one. If after decrimenting the count the count is 0
*
*/
public void access();
public void forceClose();
public void setEnterpriseBinaryComponentHelper(EnterpriseBinaryComponentHelper helper);
public EnterpriseBinaryComponentHelper getEnterpriseBinaryComponentHelper();
}
}