/******************************************************************************* * 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(); } }