| /******************************************************************************* |
| * Copyright (c) 2001, 2005 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.strategy; |
| |
| |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.File; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.SaveFailureException; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.FileIterator; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.SaveFilter; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.SaveFilterImpl; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil; |
| import org.eclipse.jst.j2ee.internal.J2EEConstants; |
| import org.eclipse.wst.common.internal.emf.resource.CompatibilityXMIResource; |
| import org.eclipse.wst.common.internal.emf.resource.TranslatorResource; |
| import org.eclipse.wst.common.internal.emf.utilities.Revisit; |
| |
| |
| /** |
| * Abstract implementer off which any save strategy can subclass |
| * |
| * @see com.ibm.etools.archive.SaveStrategy |
| */ |
| |
| public abstract class SaveStrategyImpl extends ArchiveStrategyImpl implements SaveStrategy { |
| protected SaveFilter filter; |
| |
| /** |
| * SaveStrategyImpl constructor comment. |
| */ |
| public SaveStrategyImpl() { |
| super(); |
| } |
| |
| /** |
| * The default is to do nothing - subclasses should override as necessary |
| */ |
| public void close() throws java.io.IOException { |
| //Default |
| } |
| |
| protected abstract SaveStrategy createNestedSaveStrategy(Archive anArchive) throws java.io.IOException; |
| |
| /** |
| * The default is to do nothing - subclasses should override as necessary |
| */ |
| public void finish() throws java.io.IOException { |
| //Default |
| } |
| |
| /** |
| * Insert the method's description here. Creation date: (02/28/01 4:11:28 PM) |
| * |
| * @return com.ibm.etools.archive.SaveFilter |
| */ |
| public org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.SaveFilter getFilter() { |
| if (filter == null) |
| filter = new SaveFilterImpl(); |
| return filter; |
| } |
| |
| protected abstract OutputStream getOutputStreamForResource(Resource aResource) throws java.io.IOException; |
| |
| /** |
| * @see com.ibm.etools.archive.SaveStrategy |
| */ |
| public boolean isDirectory() { |
| return false; |
| } |
| |
| protected boolean isLoadedResourceOrManifest(File aFile) { |
| return getArchive().isMofResourceLoaded(aFile.getURI()) || aFile.getURI().equals(J2EEConstants.MANIFEST_URI); |
| } |
| |
| public void save() throws SaveFailureException { |
| |
| saveManifest(); |
| saveMofResources(); |
| saveFiles(); |
| |
| } |
| |
| /** |
| * @see com.ibm.etools.archive.SaveStrategy |
| */ |
| public void save(Archive anArchive) throws SaveFailureException { |
| SaveStrategy strat = null; |
| try { |
| strat = createNestedSaveStrategy(anArchive); |
| } catch (java.io.IOException iox) { |
| throw new SaveFailureException(anArchive.getURI(), iox); |
| } |
| anArchive.save(strat); |
| |
| } |
| |
| /** |
| * @see com.ibm.etools.archive.SaveStrategy |
| */ |
| public void save(File aFile, FileIterator iterator) throws SaveFailureException { |
| if (aFile.isArchive() && shouldIterateOver((Archive) aFile)) |
| save((Archive) aFile); |
| else { |
| InputStream in = null; |
| if (!aFile.isDirectoryEntry()) { |
| try { |
| in = iterator.getInputStream(aFile); |
| } catch (IOException ex) { |
| throw new SaveFailureException(aFile.getURI(), ex); |
| } |
| } |
| save(aFile, in); |
| } |
| } |
| |
| public abstract void save(File aFile, InputStream in) throws SaveFailureException; |
| |
| protected void saveFiles() throws SaveFailureException { |
| try { |
| FileIterator iterator = getArchive().getFilesForSave(); |
| while (iterator.hasNext()) { |
| File aFile = iterator.next(); |
| if (shouldSave(aFile)) |
| save(aFile, iterator); |
| } |
| } catch (IOException iox) { |
| throw new SaveFailureException(CommonArchiveResourceHandler.Error_occurred_iterating_f_EXC_, iox); // = "Error occurred iterating files" |
| } |
| } |
| |
| protected void saveManifest() throws SaveFailureException { |
| if (!shouldSave(J2EEConstants.MANIFEST_URI)) |
| return; |
| ArchiveManifest mf = getArchive().getManifest(); |
| if (mf.getManifestVersion() == null || mf.getManifestVersion().equals(""))//$NON-NLS-1$ |
| mf.setManifestVersion("1.0");//$NON-NLS-1$ |
| save(mf); |
| } |
| |
| /** |
| * @see com.ibm.etools.archive.SaveStrategy |
| */ |
| public void saveMofResource(org.eclipse.emf.ecore.resource.Resource aResource) throws SaveFailureException { |
| if (!shouldSave(aResource)) |
| return; |
| setEncoding(aResource); |
| try { |
| boolean wasModified = aResource.isModified(); |
| OutputStream os = getOutputStreamForResource(aResource); |
| saveMofResource(aResource, os); |
| aResource.setModified(wasModified); |
| } catch (Exception e) { |
| throw new SaveFailureException(aResource.getURI().toString(), e); |
| } |
| } |
| |
| /** |
| * @see com.ibm.etools.archive.SaveStrategy |
| */ |
| protected void saveMofResource(org.eclipse.emf.ecore.resource.Resource aResource, OutputStream os) throws IOException { |
| aResource.save(os, Collections.EMPTY_MAP); |
| } |
| |
| protected void saveMofResources() throws SaveFailureException { |
| Iterator iterator = getArchive().getLoadedMofResources().iterator(); |
| //We have to go through this process because java resources could get added during the |
| //process of iterating and saving, and adding to a collection while iterating causes a |
| // failure |
| List xmiResources = new ArrayList(); |
| //We will save the xmi resources first, then the xml resources. This way the |
| //any necessary id's for referenced objects will have been generated prior to save |
| List xmlResources = new ArrayList(); |
| Resource res = null; |
| while (iterator.hasNext()) { |
| res = (Resource) iterator.next(); |
| // We don't want to save the java reflection resources or uri mapped resources |
| if (!ArchiveUtil.isJavaResource(res) && !ArchiveUtil.isRegisteredURIMapping(res) && !ArchiveUtil.isPlatformMetaResource(res)) { |
| Revisit.revisit(); |
| //For now, always use the mof5 format |
| if (res instanceof CompatibilityXMIResource) |
| ((CompatibilityXMIResource) res).setFormat(CompatibilityXMIResource.FORMAT_MOF5); |
| if (res instanceof TranslatorResource) |
| xmlResources.add(res); |
| else { |
| xmiResources.add(res); |
| } |
| } |
| } |
| basicSaveMofResources(xmiResources); |
| basicSaveMofResources(xmlResources); |
| } |
| |
| protected void basicSaveMofResources(List resources) throws SaveFailureException { |
| Resource res = null; |
| for (int i = 0; i < resources.size(); i++) { |
| res = (Resource) resources.get(i); |
| saveMofResource(res); |
| |
| } |
| } |
| |
| protected void setEncoding(Resource aResource) { |
| if (aResource instanceof org.eclipse.emf.ecore.xmi.XMLResource) |
| ((org.eclipse.emf.ecore.xmi.XMLResource) aResource).setEncoding(archive.getXmlEncoding()); |
| } |
| |
| /** |
| * Insert the method's description here. Creation date: (02/28/01 4:11:28 PM) |
| * |
| * @param newFilter |
| * com.ibm.etools.archive.SaveFilter |
| */ |
| public void setFilter(org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.SaveFilter newFilter) { |
| filter = newFilter; |
| } |
| |
| /** |
| * Answer whether the nested archive needs to be saved one file at a time, or if we can bulk |
| * save it from the original |
| */ |
| protected boolean shouldIterateOver(Archive anArchive) { |
| return anArchive.getLoadStrategy().requiresIterationOnSave(); |
| } |
| |
| protected boolean shouldSave(File aFile) { |
| boolean loaded = isLoadedResourceOrManifest(aFile); |
| if (loaded) { |
| Resource res = archive.getLoadStrategy().getExistingMofResource(aFile.getURI()); |
| if (res == null) |
| return false; |
| //must be manifest |
| return !shouldSave(res); |
| } |
| |
| if (getArchive().isModuleFile()) { |
| ModuleFile m = (ModuleFile) getArchive(); |
| if (m.getExportStrategy() != null && m.getExportStrategy().hasSaved(aFile.getURI())) |
| return false; |
| } |
| return shouldSave(aFile.getURI()); |
| } |
| |
| protected boolean shouldSave(Resource res) { |
| if (!res.isModified() && getArchive().getOptions().saveOnlyDirtyMofResources()) |
| return false; |
| |
| return shouldSave(res.getURI().toString()); |
| } |
| |
| |
| /** |
| * This is the one method through which all elements of an archive (file, nested archive, mof |
| * resource, or manifest) will be tested before saving. Subclasses can override to do something |
| * more specific |
| */ |
| protected boolean shouldSave(String uri) { |
| return getFilter().shouldSave(uri, getArchive()); |
| } |
| } |