Bug 137538 mirror command mirrors nothing if one part missing
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java
index 49bde17..abf3e7e 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java
@@ -9,10 +9,13 @@
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.update.internal.core;
+
import java.io.*;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.internal.provisional.verifier.CertificateVerifierFactory;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.*;
@@ -30,6 +33,7 @@
private ContentReference[] localFeatureFiles = new ContentReference[0];
private IVerifier jarVerifier = null;
private ExtendedSite siteModel = null;
+ private boolean continueOnError;
/*
* filter for file with .jar
*/
@@ -40,7 +44,7 @@
};
/*
- * Constructor
+ * Constructor
*/
public FeaturePackagedContentProvider(URL url, ISite site) {
super(url);
@@ -48,7 +52,7 @@
this.siteModel = (ExtendedSite) site;
}
}
-
+
/*
* Returns a new verifier for each top-level install
* (if the verifier has a parent, return the verifier
@@ -86,7 +90,7 @@
// we need to unpack archive locally for UI browser references to be resolved correctly
localFeatureFiles = featureJarReference.unpack(getWorkingDirectory(), null, monitor);
} catch (IOException e) {
- throw errorRetrieving(Feature.FEATURE_XML, featureJarReference, e); //
+ throw errorRetrieving(Feature.FEATURE_XML, featureJarReference, e);
}
// find the manifest in the unpacked feature files
@@ -153,8 +157,8 @@
currentReference = asLocalReference(currentReference, monitor);
references[0] = currentReference;
} catch (IOException e) {
- throw errorRetrieving(archiveID, currentReference, e);
- }
+ references[0] = continueOnErrorOrRethrow(archiveID, e);
+ }
return references;
}
@@ -174,7 +178,7 @@
try {
references[0] = retrieveLocalJar(new JarContentReference(archiveID, url), monitor);
} catch (IOException e) {
- throw errorRetrieving(archiveID, references[0], e);
+ references[0] = continueOnErrorOrRethrow(archiveID, e);
}
return references;
}
@@ -182,7 +186,20 @@
private ContentReference retrieveLocalJar(JarContentReference reference, InstallMonitor monitor) throws IOException, CoreException {
//If the site does not support pack200, just get the jar as normal
if(siteModel == null || !siteModel.supportsPack200() || !JarProcessor.canPerformUnpack()) {
- return asLocalReference(reference, monitor);
+ ContentReference contentReference = null;
+ try {
+ contentReference = asLocalReference(reference, monitor);
+ }
+ catch (FileNotFoundException e) {
+ contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+ }
+ catch (IOException e) {
+ contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+ }
+ catch (CoreException e) {
+ contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+ }
+ return contentReference;
}
ContentReference packedRef = null;
@@ -247,6 +264,7 @@
}
return packedRef;
}
+
/*
* @see IFeatureContentProvider#getNonPluginEntryArchiveReferences(INonPluginEntry)
*/
@@ -269,12 +287,13 @@
references[0] = currentReference;
} catch (IOException e) {
- throw errorRetrieving(archiveID, currentReference, e);
+ references[0] = continueOnErrorOrRethrow(archiveID, e);
}
return references;
}
+
/*
* @see IFeatureContentProvider#getFeatureEntryContentReferences()
*/
@@ -349,4 +368,58 @@
}
+
+ public void setContinueOnError(boolean continueOnError) {
+ this.continueOnError = continueOnError;
+ }
+
+ /**
+ * This method is used for when a core exception is detected, so, if its decided to rethrow, then
+ * a core exception odes not have to be recreated.
+ *
+ * @param archiveID id of the archive file
+ * @param CoreException
+ * @return NullReference if its decided not to continue
+ * @throws CoreException
+ */
+ private ContentReference continueOrErrorOrRethrow(String archiveID, CoreException coreException) throws CoreException {
+ ContentReference reference = null;
+
+ if (continueOnError) {
+ // this ContentReference without a file or URL is purely a
+ // "missing jar" reference.
+ reference = new NullContentReference(archiveID);
+
+ String msg = " ContinueOnError: The following ID was not found, so was skipped, and is not on miror site: " + archiveID; //$NON-NLS-1$
+ String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
+ IStatus status = new Status(IStatus.WARNING, id , 0, msg, null);
+ UpdateCore.log(status);
+
+ }
+ else {
+ throw coreException;
+ }
+ return reference;
+ }
+
+ private ContentReference continueOnErrorOrRethrow(String archiveID, Exception e) throws CoreException {
+ ContentReference reference = null;
+
+ if (continueOnError) {
+ // this ContentReference without a file or URL is purely a
+ // "missing jar" reference.
+ reference = new NullContentReference(archiveID);
+
+ String msg = " ContinueOnError: The following ID was not found, so was skipped, and is not on miror site: " + archiveID; //$NON-NLS-1$
+ String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
+ IStatus status = new Status(IStatus.WARNING, id , 0, msg, null);
+ UpdateCore.log(status);
+
+ }
+ else {
+ throw errorRetrieving(archiveID, reference, e);
+ }
+ return reference;
+ }
+
}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NullContentReference.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NullContentReference.java
new file mode 100644
index 0000000..963fa1d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NullContentReference.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 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.update.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.update.core.ContentReference;
+
+/**
+ * NullContentReference implements a general access wrapper
+ * to feature and site content -- but, for which, there is no
+ * content actually found. This way, it can "keep" the ID that was
+ * requested, and still hold a place in lists and arrays, without a
+ * change to other program logic. It does, how ever require the internal
+ * algorithms to be more careful about assumptions made ... for example,
+ * just because asFile is null, it does not follow that asURL will not be null.
+ * <p>
+ * This class may not be instantiated or subclassed by clients.
+ * </p>
+ * @see org.eclipse.update.core.ContentReference
+ * @see org.eclipse.update.core.JarContentReference
+ * @see org.eclipse.update.core.JarEntryContentReference
+ */
+public class NullContentReference extends ContentReference {
+
+
+ /**
+ * Contructor for the "missing jar" case.
+ *
+ * @param id
+ */
+ public NullContentReference(String id) {
+ super(id, (File) null);
+ }
+ /**
+ * A factory method to create a content reference of
+ * the same type.
+ *
+ * @param id "symbolic" path identifier
+ */
+ public ContentReference createContentReference(String id, File file) {
+ return new NullContentReference(id);
+ }
+
+ /**
+ * Overrides super class implementation to avoid throwing a FileNotFound exception.
+ *
+ * @return null
+ */
+ public InputStream getInputStream() throws IOException {
+ return null;
+ }
+ /**
+ * Overrides super class implementation to avoid throwing a FileNotFound exception.
+ *
+ * @return null
+ */
+ public File asFile() throws IOException {
+ return null;
+ }
+
+ /**
+ * Overrides super class implementation to avoid throwing URL exceptions.
+ *
+ * @return null
+ */
+ public URL asURL() throws IOException {
+ return null;
+ }
+
+ /**
+ * Return string representation of this reference.
+ *
+ * @return string representation
+ */
+ public String toString() {
+ return "Missing archive file: " + '(' + getIdentifier() + ')'; //$NON-NLS-1$
+ }
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java
index e9c440b..b5fec0c 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java
@@ -46,6 +46,7 @@
import org.eclipse.update.core.model.URLEntryModel;
import org.eclipse.update.internal.core.CoreExceptionWithRootCause;
import org.eclipse.update.internal.core.FatalIOException;
+import org.eclipse.update.internal.core.FeaturePackagedContentProvider;
import org.eclipse.update.internal.core.ISiteContentConsumer;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.core.UpdateManagerUtils;
@@ -190,6 +191,13 @@
final IFeatureContentProvider provider =
sourceFeature.getFeatureContentProvider();
+
+ // TODO: passing command options could be made more general in future, so this
+ // cast is not needed.
+ if (provider instanceof FeaturePackagedContentProvider) {
+ ((FeaturePackagedContentProvider) provider).setContinueOnError(ignoreNonPresentPlugins);
+ }
+
System.out.println(
tab
+ "Getting plugin entries for " //$NON-NLS-1$
@@ -452,7 +460,10 @@
URL newURL = new URL(getURL(), contentReference.getIdentifier());
pluginPath = newURL.getFile();
inStream = contentReference.getInputStream();
- UpdateManagerUtils.copyToLocal(inStream, pluginPath, null);
+ // added null check here, since contentReference can, in theory, return null for input stream.
+ if (inStream != null) {
+ UpdateManagerUtils.copyToLocal(inStream, pluginPath, null);
+ }
} catch (IOException e) {
throw Utilities.newCoreException(
"Error occurred while creating "+ pluginPath+" file.", //$NON-NLS-1$ //$NON-NLS-2$
@@ -704,7 +715,13 @@
URLEntryModel newUrlEntryModel = new URLEntryModel();
URL url = urlEntry.getURL();
newUrlEntryModel.setAnnotation(urlEntry.getAnnotation());
- newUrlEntryModel.setURLString(url.toExternalForm());
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=136249
+ // URL is not required, so might be null
+ // The null case is (already) handled correctly in
+ // writeDescription
+ if (url != null) {
+ newUrlEntryModel.setURLString(url.toExternalForm());
+ }
this.setDescriptionModel(newUrlEntryModel);
}
}