Java tutorial
// ============================================================================ // // Copyright (C) 2006-2018 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.updates.runtime.model; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.core.IProvisioningAgentProvider; import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.equinox.p2.engine.IPhaseSet; import org.eclipse.equinox.p2.engine.IProfile; import org.eclipse.equinox.p2.engine.IProfileRegistry; import org.eclipse.equinox.p2.engine.PhaseSetFactory; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.operations.InstallOperation; import org.eclipse.equinox.p2.operations.ProfileModificationJob; import org.eclipse.equinox.p2.operations.ProvisioningSession; import org.eclipse.equinox.p2.operations.Update; import org.eclipse.equinox.p2.operations.UpdateOperation; import org.eclipse.equinox.p2.query.IQuery; import org.eclipse.equinox.p2.query.IQueryResult; import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.equinox.p2.repository.IRepositoryManager; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.PlatformUI; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import org.talend.commons.exception.ExceptionHandler; import org.talend.core.GlobalServiceRegister; import org.talend.core.services.ICoreTisService; import org.talend.updates.runtime.engine.P2Manager; import org.talend.updates.runtime.feature.model.Category; import org.talend.updates.runtime.feature.model.Type; import org.talend.updates.runtime.i18n.Messages; import org.talend.updates.runtime.model.InstallationStatus.Status; import org.talend.updates.runtime.model.interfaces.IP2Feature; import org.talend.updates.runtime.nexus.component.ComponentIndexBean; import org.talend.updates.runtime.nexus.component.ComponentIndexManager; import org.talend.updates.runtime.service.ITaCoKitUpdateService; import org.talend.updates.runtime.service.ITaCoKitUpdateService.ICarInstallationResult; import org.talend.updates.runtime.storage.AbstractFeatureStorage; import org.talend.updates.runtime.storage.IFeatureStorage; import org.talend.updates.runtime.utils.PathUtils; import org.talend.updates.runtime.utils.TaCoKitCarUtils; import org.talend.utils.files.FileUtils; import org.talend.utils.io.FilesUtils; import org.talend.utils.json.JSONException; import org.talend.utils.json.JSONObject; /** * created by sgandon on 19 fvr. 2013 This class represent an extra feature defined in the License in the document : * https://wiki.talend.com/x/YoVL * */ public class P2ExtraFeature extends AbstractExtraFeature implements IP2Feature { private String baseRepoUriStr;// default url of the remote repo where to look for the feature to install /** * default is false, in case cache can't be refreshed */ private boolean useP2Cache = false; public P2ExtraFeature() { this(null, null, null, null, null, null, null, null, null, null, null, false, null, false, false); } public P2ExtraFeature(ComponentIndexBean indexBean) { this(indexBean.getName(), indexBean.getVersion(), indexBean.getDescription(), indexBean.getMvnURI(), indexBean.getImageMvnURI(), indexBean.getProduct(), indexBean.getCompatibleStudioVersion(), indexBean.getBundleId(), PathUtils.convert2Types(indexBean.getTypes()), PathUtils.convert2Categories(indexBean.getCategories()), Boolean.valueOf(indexBean.getDegradable())); } public P2ExtraFeature(final File zipFile) { this(new ComponentIndexManager().create(zipFile)); setStorage(new AbstractFeatureStorage() { @Override protected File downloadImageFile(IProgressMonitor monitor) throws Exception { return null; } @Override protected File downloadFeatureFile(IProgressMonitor monitor) throws Exception { return zipFile; } }); } public P2ExtraFeature(String name, String version, String description, String mvnUri, String imageMvnUri, String product, String compatibleStudioVersion, String p2IuId, Collection<Type> types, Collection<Category> categories, boolean degradable) { this(p2IuId, name, version, description, mvnUri, imageMvnUri, product, compatibleStudioVersion, null, types, categories, degradable, null, false, true); } public P2ExtraFeature(String p2IuId, String name, String version, String description, String mvnUri, String imageMvnUri, String product, String compatibleStudioVersion, FeatureCategory parentCategory, Collection<Type> types, Collection<Category> categories, boolean degradable, String baseRepoUriStr, boolean mustBeInstalled, boolean useLegacyP2Install) { super(p2IuId, name, version, description, mvnUri, imageMvnUri, product, compatibleStudioVersion, parentCategory, types, categories, degradable, mustBeInstalled, useLegacyP2Install); this.baseRepoUriStr = baseRepoUriStr; } public Set<IInstallableUnit> getInstalledIUs(String p2IuId2, IProgressMonitor progress) throws ProvisionException { SubMonitor subMonitor = SubMonitor.convert(progress, 2); subMonitor.setTaskName(Messages.getString("ExtraFeature.checking.is.installed", getName())); //$NON-NLS-1$ Bundle bundle = FrameworkUtil.getBundle(org.eclipse.equinox.p2.query.QueryUtil.class);// not using this context // caus junit fails BundleContext context = bundle.getBundleContext(); ServiceReference sr = context.getServiceReference(IProvisioningAgentProvider.SERVICE_NAME); if (sr == null) { throw new ProvisionException(Messages.getString("ExtraFeature.p2.agent.service.not.found"));//$NON-NLS-1$ } IProvisioningAgentProvider agentProvider = (IProvisioningAgentProvider) context.getService(sr); if (agentProvider == null) { throw new ProvisionException(Messages.getString("ExtraFeature.p2.agent.provider.not.found")); //$NON-NLS-1$ } IProvisioningAgent agent = null; try { IQuery<IInstallableUnit> iuQuery = QueryUtil.createIUQuery(p2IuId2); boolean interrupted = false; IProfile profile = null; // there seems to be a bug because if the agent is created too quickly then the profile is empty. // so we loop until we get a proper profile final String p2ProfileId = getP2ProfileId(); do { try { Thread.sleep(50); } catch (InterruptedException e) { interrupted = true; } if (agent != null) { agent.stop(); } agent = agentProvider.createAgent(getP2AgentUri()); IProfileRegistry profRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); profile = profRegistry.getProfile(p2ProfileId); } while (profile != null && profile.getTimestamp() == 0 && !interrupted && !subMonitor.isCanceled()); if (profile == null || subMonitor.isCanceled()) { throw new ProvisionException("Could not find the p2 profile named " + p2ProfileId); //$NON-NLS-1$ } subMonitor.worked(1); IQueryResult<IInstallableUnit> iuQueryResult = profile.available(iuQuery, subMonitor.newChild(1)); if (subMonitor.isCanceled()) { return Collections.EMPTY_SET; } return iuQueryResult.toSet(); } finally { if (agent != null) { agent.stop(); } } } /** * created for JUnit test so that profile Id can be changed by overriding * * @return */ public String getP2ProfileId() { return "_SELF_"; //$NON-NLS-1$ } /** * create for JUnit test so that URI can be change to some other P2 repo * * @return null for using the current defined area, but may be overriden ot point to another area for JUnitTests */ public URI getP2AgentUri() { return null; } public URI getP2RepositoryURI() { IFeatureStorage storage = getStorage(); if (storage != null) { try { File featureFile = storage.getFeatureFile(new NullProgressMonitor()); if (featureFile != null) { URI repositoryURI = PathUtils.getP2RepURIFromCompFile(featureFile); if (repositoryURI != null) { return repositoryURI; } } } catch (Exception e) { ExceptionHandler.process(e); } } return getP2RepositoryURI(null, false); } /** * this is the base URI set in the license. * * @return the defaultRepoUriStr */ public String getBaseRepoUriString() { return this.baseRepoUriStr; } public void setBaseRepoUriString(String baseRepoUriStr) { this.baseRepoUriStr = baseRepoUriStr; } public URI getP2RepositoryURI(String key, boolean isTOS) { String uriString = getBaseRepoUriString(); if (key == null) { key = "talend.p2.repo.url"; //$NON-NLS-1$ } String p2RepoUrlFromProp = System.getProperty(key); if (!isTOS && p2RepoUrlFromProp != null) { uriString = p2RepoUrlFromProp; } else { String version = PathUtils.getTalendVersionStr(); if (uriString == null) { return URI.create(version); } uriString = uriString + (uriString.endsWith("/") ? "" : "/") + version; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } return URI.create(uriString); } /* * (non-Javadoc) * * @see org.talend.updates.model.ExtraFeature#install(org.eclipse.core.runtime.IProgressMonitor, java.util.List) */ @Override public IStatus install(final IProgressMonitor progress, List<URI> allRepoUris) throws ExtraFeatureException { IStatus doInstallStatus = null; File configIniBackupFile = null; Map<File, File> unzippedPatches = new HashMap<>(); try { if (!isUseLegacyP2Install()) { // backup the config.ini configIniBackupFile = copyConfigFile(null); } // else legacy p2 install will update the config.ini doInstallStatus = installP2(progress, allRepoUris); if (doInstallStatus == null || !doInstallStatus.isOK()) { return doInstallStatus; } unzippedPatches = unzipPatches(progress, allRepoUris); storeInstalledFeatureMessage(); } catch (IOException e) { throw new ExtraFeatureException(new ProvisionException( Messages.createErrorStatus(e, "ExtraFeaturesFactory.restore.config.error"))); //$NON-NLS-1$ } finally { boolean isInstalled = false; if (doInstallStatus != null) { switch (doInstallStatus.getSeverity()) { case IStatus.OK: case IStatus.INFO: case IStatus.WARNING: isInstalled = true; break; default: isInstalled = false; break; } } IProgressMonitor monitor2 = progress; if (isInstalled) { if (progress != null) { monitor2 = (IProgressMonitor) Proxy.newProxyInstance(progress.getClass().getClassLoader(), new Class[] { IProgressMonitor.class }, new InvocationHandler() { @Override public Object invoke(Object obj, Method method, Object[] args) throws Throwable { if (method == null) { return null; } if (StringUtils.equals(method.getName(), "isCanceled")) { //$NON-NLS-1$ return Boolean.FALSE; } return method.invoke(progress, args); } }); } try { afterInstallP2(monitor2, unzippedPatches); } catch (Exception e) { ExceptionHandler.process(e); } } // restore the config.ini if (configIniBackupFile != null) { // must existed backup file. try { copyConfigFile(configIniBackupFile); } catch (IOException e) { throw new P2ExtraFeatureException(new ProvisionException( Messages.createErrorStatus(e, "ExtraFeaturesFactory.back.config.error"))); //$NON-NLS-1$ } } if (isInstalled) { try { afterRestoreConfigFile(monitor2, unzippedPatches); } catch (Exception e) { ExceptionHandler.process(e); } } if (unzippedPatches != null && !unzippedPatches.isEmpty()) { for (Map.Entry<File, File> patchEntry : unzippedPatches.entrySet()) { FilesUtils.deleteFolder(patchEntry.getValue(), true); } } } return doInstallStatus; } protected void afterInstallP2(IProgressMonitor progress, Map<File, File> unzippedPatchMap) throws P2ExtraFeatureException { P2Manager.getInstance().clearOsgiCache(); } protected void afterRestoreConfigFile(IProgressMonitor progress, Map<File, File> unzippedPatchMap) throws P2ExtraFeatureException { installCars(progress, unzippedPatchMap); } protected void storeInstalledFeatureMessage() { IPreferenceStore preferenceStore = PlatformUI.getPreferenceStore(); String addons = preferenceStore.getString("ADDONS"); //$NON-NLS-1$ JSONObject allAddons = null; try { allAddons = new JSONObject(addons); } catch (Exception e) { // the value is not set, or is empty allAddons = new JSONObject(); } try { allAddons.put(getName(), ""); //$NON-NLS-1$ preferenceStore.setValue("ADDONS", allAddons.toString()); //$NON-NLS-1$ } catch (JSONException e) { ExceptionHandler.process(e); } } protected IStatus installP2(IProgressMonitor progress, List<URI> allRepoUris) throws P2ExtraFeatureException { SubMonitor subMonitor = SubMonitor.convert(progress, 5); subMonitor.setTaskName(Messages.getString("ExtraFeature.installing.feature", getName())); //$NON-NLS-1$ // reset isInstalled to make is compute the next time is it used setIsInstalled(null); // we are not using this bundles context caus it fails to be aquired in junit test Bundle bundle = FrameworkUtil.getBundle(org.eclipse.equinox.p2.query.QueryUtil.class); BundleContext context = bundle.getBundleContext(); ServiceReference sr = context.getServiceReference(IProvisioningAgentProvider.SERVICE_NAME); if (sr == null) { return Messages.createErrorStatus(null, "ExtraFeature.p2.agent.service.not.found", getName(), //$NON-NLS-1$ getVersion()); } IProvisioningAgentProvider agentProvider = (IProvisioningAgentProvider) context.getService(sr); if (agentProvider == null) { return Messages.createErrorStatus(null, "ExtraFeature.p2.agent.provider.not.found", getName(), //$NON-NLS-1$ getVersion()); } IProvisioningAgent agent = null; try { agent = agentProvider.createAgent(getP2AgentUri()); updateRoamingProp(agent, agentProvider); Set<IInstallableUnit> toInstall = getInstallableIU(agent, allRepoUris, subMonitor.newChild(1)); if (subMonitor.isCanceled()) { return Messages.createCancelStatus("user.cancel.installation.of.feature", //$NON-NLS-1$ getName()); } // show the installation unit log.debug("ius to be installed:" + toInstall); //$NON-NLS-1$ if (toInstall.isEmpty()) { return Messages.createErrorStatus(null, "ExtraFeature.could.not.find.feature", getName(), //$NON-NLS-1$ getP2IuId(), Arrays.toString(allRepoUris.toArray(new URI[allRepoUris.size()]))); } // install InstallOperation installOperation = new InstallOperation(new ProvisioningSession(agent), toInstall); installOperation.setProfileId(getP2ProfileId()); IStatus installResolvedStatus = installOperation.resolveModal(subMonitor.newChild(1)); if (subMonitor.isCanceled()) { return Messages.createCancelStatus("user.cancel.installation.of.feature", //$NON-NLS-1$ getName()); } if (installResolvedStatus.getSeverity() == IStatus.ERROR) { return Messages.createErrorStatus(null, "ExtraFeature.error.installing.new.feature", //$NON-NLS-1$ installOperation.getResolutionDetails()); } // else perform the installlation IPhaseSet talendPhaseSet = PhaseSetFactory .createDefaultPhaseSetExcluding(new String[] { PhaseSetFactory.PHASE_CHECK_TRUST }); ProfileModificationJob provisioningJob = (ProfileModificationJob) installOperation .getProvisioningJob(subMonitor.newChild(1)); if (subMonitor.isCanceled()) { return Messages.createCancelStatus("user.cancel.installation.of.feature", //$NON-NLS-1$ getName()); } if (provisioningJob == null) { return Messages.createErrorStatus(null, "ExtraFeature.error.installing.new.feature", //$NON-NLS-1$ installOperation.getResolutionDetails()); } provisioningJob.setPhaseSet(talendPhaseSet); IStatus status = provisioningJob.run(subMonitor.newChild(1)); if (subMonitor.isCanceled()) { return Messages.createCancelStatus("user.cancel.installation.of.feature", //$NON-NLS-1$ getName()); } log.debug("installed extra feature " + getName() + " (" + getVersion() + ") with status :" + status); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } catch (URISyntaxException e) { return Messages.createErrorStatus(e, "ExtraFeature.error.installing.feature.uri.exception", getName(), //$NON-NLS-1$ getVersion()); } catch (ProvisionException e) { return Messages.createErrorStatus(e, "ExtraFeature.error.installing.feature.uri.exception", getName(), //$NON-NLS-1$ getVersion()); } finally { if (agent != null) {// agent creation did not fail removeAllRepositories(agent, allRepoUris); agent.stop(); } } return Messages.createOkStatus("sucessfull.install.of.feature", getName()); //$NON-NLS-1$ } /** * DOC sgandon Comment method "removeAllRepositories". * * @param agent * @param allRepoUris */ protected void removeAllRepositories(IProvisioningAgent agent, List<URI> allRepoUris) { // get the repository managers and remove all repositories IMetadataRepositoryManager metadataManager = (IMetadataRepositoryManager) agent .getService(IMetadataRepositoryManager.SERVICE_NAME); IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) agent .getService(IArtifactRepositoryManager.SERVICE_NAME); for (URI repoUri : allRepoUris) { metadataManager.removeRepository(repoUri); artifactManager.removeRepository(repoUri); // metadataManager.loadRepository(repoUri, subMonitor.newChild(1)); } } /** * add the feauture repo URI to the p2 engine and return the P2 installable units by looking at each repo * sequentially. * * @param agent * @return the metadata repo to install anything in it. * @throws URISyntaxException if the feature remote p2 site uri is bad * @throws OperationCanceledException if installation was canceled * @throws ProvisionException if p2 repository could not be loaded */ protected Set<IInstallableUnit> getInstallableIU(IProvisioningAgent agent, List<URI> allRepoUris, IProgressMonitor progress) throws URISyntaxException, ProvisionException, OperationCanceledException { if (allRepoUris.isEmpty()) {// if repo list is empty use the default URI allRepoUris.add(getP2RepositoryURI()); } SubMonitor subMonitor = SubMonitor.convert(progress, allRepoUris.size()); subMonitor.setTaskName(Messages.getString("ExtraFeature.searching.talend.features.label", getName())); //$NON-NLS-1$ // get the repository managers and add our repository IMetadataRepositoryManager metadataManager = (IMetadataRepositoryManager) agent .getService(IMetadataRepositoryManager.SERVICE_NAME); IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) agent .getService(IArtifactRepositoryManager.SERVICE_NAME); // create the feature query IQuery<IInstallableUnit> iuQuery = QueryUtil.createLatestQuery(QueryUtil.createIUQuery(getP2IuId())); // remove existing repositories for (URI existingRepUri : metadataManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)) { metadataManager.removeRepository(existingRepUri); } for (URI existingRepUri : artifactManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)) { metadataManager.removeRepository(existingRepUri); } for (URI repoUri : allRepoUris) { metadataManager.addRepository(repoUri); artifactManager.addRepository(repoUri); } if (subMonitor.isCanceled()) { return Collections.EMPTY_SET; } return metadataManager.query(iuQuery, progress).toUnmodifiableSet(); } /** * Created for JUnit test so that external P2 data area does not depend on absolute location * * @param agent * @param agentProvider * @throws ProvisionException */ protected void updateRoamingProp(IProvisioningAgent agent, IProvisioningAgentProvider agentProvider) throws ProvisionException { agent.registerService(IProvisioningAgent.INSTALLER_AGENT, agentProvider.createAgent(null)); agent.registerService("eclipse.p2.profile", getP2ProfileId());//$NON-NLS-1$ } /** * Check that the remote update site has a different version from the one already installed. If that is the case * then a new instance of P2ExtraFeature is create, it returns null otherwhise. * * @param progress * @return a new P2ExtraFeature if the update site contains a new version of the feature or null. */ @Override public ExtraFeature createFeatureIfUpdates(IProgressMonitor progress) throws ProvisionException { return createFeatureIfUpdates(progress, Collections.singletonList(getP2RepositoryURI())); } /** * Check that the remote update site has a different version from the one already installed. If that is the case * then a new instance of P2ExtraFeature is create, it returns null otherwhise. * * @param allRepoUrisn list of the repos to look for an update * @param progress * @return a new P2ExtraFeature if the update site contains a new version of the feature or null. */ public ExtraFeature createFeatureIfUpdates(IProgressMonitor progress, List<URI> allRepoUris) throws ProvisionException { if (progress.isCanceled()) { return null; } // get the installed IUs SubMonitor subMonitor = SubMonitor.convert(progress, Messages.getString("ExtraFeature.checking.need.update", getName()), //$NON-NLS-1$ 2); subMonitor.setTaskName(Messages.getString("ExtraFeature.checking.need.update", getName())); //$NON-NLS-1$ Bundle bundle = FrameworkUtil.getBundle(org.eclipse.equinox.p2.query.QueryUtil.class);// not using this context // caus junit fails BundleContext context = bundle.getBundleContext(); ServiceReference sr = context.getServiceReference(IProvisioningAgentProvider.SERVICE_NAME); if (sr == null) { throw new ProvisionException(Messages.getString("ExtraFeature.p2.agent.service.not.found"));//$NON-NLS-1$ } IProvisioningAgentProvider agentProvider = (IProvisioningAgentProvider) context.getService(sr); if (agentProvider == null) { throw new ProvisionException(Messages.getString("ExtraFeature.p2.agent.provider.not.found")); //$NON-NLS-1$ } IProvisioningAgent agent = null; try { IQuery<IInstallableUnit> iuQuery = QueryUtil.createIUQuery(getP2IuId()); boolean interrupted = false; IProfile profile = null; // there seems to be a bug because if the agent is created too quickly then the profile is empty. // so we loop until we get a proper profile do { try { Thread.sleep(50); } catch (InterruptedException e) { interrupted = true; } if (agent != null) { agent.stop(); } agent = agentProvider.createAgent(getP2AgentUri()); updateRoamingProp(agent, agentProvider); IProfileRegistry profRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME); profile = profRegistry.getProfile(getP2ProfileId()); } while (profile != null && profile.getTimestamp() == 0 && !interrupted && !progress.isCanceled()); if (profile == null || subMonitor.isCanceled()) { throw new ProvisionException("Could not find the p2 profile named _SELF_"); //$NON-NLS-1$ } subMonitor.worked(1); IQueryResult<IInstallableUnit> iuQueryResult = profile.available(iuQuery, subMonitor.newChild(1)); if (subMonitor.isCanceled() || iuQueryResult.isEmpty()) { return null; } // now we have the IU to be updated then we check is any update is available log.debug("ius to be be checked for updates:" + iuQueryResult.toSet()); //$NON-NLS-1$ // install UpdateOperation updateOperation = new UpdateOperation(new ProvisioningSession(agent), iuQueryResult.toSet()); updateOperation.getProvisioningContext() .setArtifactRepositories(allRepoUris.toArray(new URI[allRepoUris.size()])); updateOperation.getProvisioningContext() .setMetadataRepositories(allRepoUris.toArray(new URI[allRepoUris.size()])); updateOperation.setProfileId(getP2ProfileId()); updateOperation.resolveModal(subMonitor.newChild(1)); if (subMonitor.isCanceled()) { return null; } P2ExtraFeature p2ExtraFeatureUpdate = new P2ExtraFeature(); copyFieldInto(p2ExtraFeatureUpdate); Update[] selectedUpdates = updateOperation.getSelectedUpdates(); if (selectedUpdates == null || selectedUpdates.length == 0) { return null; } // else at least one udpate is availalble. // take the first update. p2ExtraFeatureUpdate.setVersion(selectedUpdates[0].replacement.getVersion().getOriginal()); return p2ExtraFeatureUpdate; } finally { if (agent != null) {// agent creation did not fail removeAllRepositories(agent, allRepoUris); agent.stop(); } } } @Override public void copyFieldInto(AbstractExtraFeature p2ExtraFeatureUpdate) { super.copyFieldInto(p2ExtraFeatureUpdate); if (p2ExtraFeatureUpdate instanceof P2ExtraFeature) { ((P2ExtraFeature) p2ExtraFeatureUpdate).baseRepoUriStr = baseRepoUriStr; } } /** * copy the config.ini to a temporary file or vise versa is toRestore is not null * * @param toResore file to be copied to config.ini * @return the temporary file to restore or null if toRestore is not null * @throws IOException */ protected File copyConfigFile(File toResore) throws IOException { File tempFile = null; try { File configurationFile = PathUtils.getStudioConfigFile(); if (toResore != null) { if (GlobalServiceRegister.getDefault().isServiceRegistered(ICoreTisService.class)) { ICoreTisService coreTisService = (ICoreTisService) GlobalServiceRegister.getDefault() .getService(ICoreTisService.class); coreTisService.updateConfiguratorBundles(configurationFile, toResore); } } else { tempFile = File.createTempFile("config.ini", null); //$NON-NLS-1$ FilesUtils.copyFile(new FileInputStream(configurationFile), tempFile); } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e); } finally { if (toResore != null && toResore.exists()) { toResore.delete(); } } return tempFile; } @Override public ExtraFeature getInstalledFeature(IProgressMonitor progress) throws ExtraFeatureException { ExtraFeature extraFeature = null; try { if (!this.isInstalled(progress)) { // new extraFeature = this; } else {// else already installed so try to find updates extraFeature = this.createFeatureIfUpdates(progress); } } catch (Exception e) { throw new ExtraFeatureException(e); } return extraFeature; } protected Map<File, File> unzipPatches(IProgressMonitor progress, List<URI> allRepoUris) throws ExtraFeatureException { if (allRepoUris == null || allRepoUris.size() == 0) { return Collections.EMPTY_MAP; } if (progress.isCanceled()) { throw new OperationCanceledException(); } Map<File, File> unzippedMap = new HashMap<>(); progress.beginTask(Messages.getString("P2ExtraFeature.progress.unzipPatch"), allRepoUris.size()); //$NON-NLS-1$ try { for (URI uri : allRepoUris) { File compFile = PathUtils.getCompFileFromP2RepURI(uri); if (compFile != null && compFile.exists()) { // sync the component libraries File tempUpdateSiteFolder = getTempUpdateSiteFolder(); FilesUtils.unzip(compFile.getAbsolutePath(), tempUpdateSiteFolder.getAbsolutePath()); unzippedMap.put(compFile, tempUpdateSiteFolder); progress.worked(1); } } return unzippedMap; } catch (Exception e) { throw new P2ExtraFeatureException(e); } } protected void installCars(IProgressMonitor progress, Map<File, File> unzippedPatchMap) throws P2ExtraFeatureException { if (unzippedPatchMap == null || unzippedPatchMap.isEmpty()) { return; } if (progress.isCanceled()) { throw new OperationCanceledException(); } try { for (Map.Entry<File, File> patchEntry : unzippedPatchMap.entrySet()) { File patchFile = patchEntry.getKey(); File unzippedPatchFolder = patchEntry.getValue(); installCars(progress, patchFile, unzippedPatchFolder); } } catch (Exception e) { throw new P2ExtraFeatureException(e); } } protected void installCars(IProgressMonitor progress, File zipFile, File unzippedFolder) throws Exception { try { File carFolder = new File(unzippedFolder, ITaCoKitUpdateService.FOLDER_CAR); // car ICarInstallationResult result = TaCoKitCarUtils.installCars(carFolder, progress); if (result != null) { if (result.needRestart()) { setNeedRestart(result.needRestart()); } } } catch (Exception e) { log.error(e.getMessage()); } } protected File getTempUpdateSiteFolder() { return FileUtils.createTmpFolder("p2updatesite", null); //$NON-NLS-1$ } @Override public boolean canBeInstalled(IProgressMonitor progress) throws ExtraFeatureException { try { InstallationStatus installationStatus = getInstallationStatus(progress); return installationStatus.canBeInstalled(); } catch (Exception e) { throw new ExtraFeatureException(e); } } @Override public InstallationStatus getInstallationStatus(IProgressMonitor monitor) throws Exception { Collection<IInstallableUnit> installedP2s = P2Manager.getInstance().getInstalledP2Feature(monitor, getP2IuId(), null, useP2Cache()); if (installedP2s != null && !installedP2s.isEmpty()) { Version installedLatestVersion = null; for (IInstallableUnit installedP2 : installedP2s) { Version installedVersion = installedP2.getVersion(); if (installedVersion != null) { if (installedLatestVersion == null) { installedLatestVersion = installedVersion; } else { if (installedLatestVersion.compareTo(installedVersion) < 0) { installedLatestVersion = installedVersion; } } } } String installedLastestVersionStr = null; String version = getVersion(); if (installedLatestVersion != null) { installedLastestVersionStr = installedLatestVersion.toString(); } InstallationStatus status = PathUtils.getInstallationStatus(installedLastestVersionStr, version); status.setRequiredStudioVersion(getCompatibleStudioVersion()); return status; } InstallationStatus status = new InstallationStatus(Status.INSTALLABLE); status.setRequiredStudioVersion(getCompatibleStudioVersion()); return status; } @Override public void setUseP2Cache(boolean useP2Cache) { this.useP2Cache = useP2Cache; } @Override public boolean useP2Cache() { return this.useP2Cache; } }