1 /******************************************************************************* 2 * Copyright (c) 2007, 2017 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Red Hat, Inc - fragments support added 14 *******************************************************************************/ 15 package org.eclipse.equinox.internal.p2.engine; 16 17 import java.io.*; 18 import java.net.URI; 19 import java.net.URISyntaxException; 20 import java.nio.file.Files; 21 import java.util.*; 22 import org.eclipse.core.runtime.IStatus; 23 import org.eclipse.core.runtime.Status; 24 import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; 25 import org.eclipse.osgi.util.NLS; 26 import org.osgi.framework.BundleActivator; 27 import org.osgi.framework.BundleContext; 28 29 public class EngineActivator implements BundleActivator { 30 private static BundleContext context; 31 /** 32 * as for now it is exactly the same variable as in simpleconfigurator Activator 33 * @noreference This field is not intended to be referenced by clients. 34 */ 35 public static String EXTENSIONS = System.getProperty("p2.fragments"); //$NON-NLS-1$ 36 public static boolean EXTENDED = EXTENSIONS != null; 37 private static final String LINK_KEY = "link"; //$NON-NLS-1$ 38 private static final String LINK_FILE_EXTENSION = ".link"; //$NON-NLS-1$ 39 private static final Set<File> reportedExtensions = Collections.synchronizedSet(new HashSet<File>(0)); 40 41 public static final String ID = "org.eclipse.equinox.p2.engine"; //$NON-NLS-1$ 42 43 /** 44 * System property describing the profile registry file format 45 */ 46 public static final String PROP_PROFILE_FORMAT = "eclipse.p2.profileFormat"; //$NON-NLS-1$ 47 48 /** 49 * Value for the PROP_PROFILE_FORMAT system property specifying raw XML file 50 * format (used in p2 until and including 3.5.0 release). 51 */ 52 public static final String PROFILE_FORMAT_UNCOMPRESSED = "uncompressed"; //$NON-NLS-1$ 53 54 /** 55 * System property specifying how the engine should handle unsigned artifacts. 56 * If this property is undefined, the default value is assumed to be "prompt". 57 */ 58 public static final String PROP_UNSIGNED_POLICY = "eclipse.p2.unsignedPolicy"; //$NON-NLS-1$ 59 60 /** 61 * System property value specifying that the engine should prompt for confirmation 62 * when installing unsigned artifacts. 63 */ 64 public static final String UNSIGNED_PROMPT = "prompt"; //$NON-NLS-1$ 65 66 /** 67 * System property value specifying that the engine should fail when an attempt 68 * is made to install unsigned artifacts. 69 */ 70 public static final String UNSIGNED_FAIL = "fail"; //$NON-NLS-1$ 71 72 /** 73 * System property value specifying that the engine should silently allow unsigned 74 * artifacts to be installed. 75 */ 76 public static final String UNSIGNED_ALLOW = "allow"; //$NON-NLS-1$ 77 getContext()78 public static BundleContext getContext() { 79 return context; 80 } 81 82 /** 83 * This property indicates repositories that are passed via the fragments mechanism. 84 */ 85 public static final String P2_FRAGMENT_PROPERTY = "p2.fragment"; //$NON-NLS-1$ 86 87 @Override start(BundleContext aContext)88 public void start(BundleContext aContext) throws Exception { 89 EngineActivator.context = aContext; 90 } 91 92 @Override stop(BundleContext aContext)93 public void stop(BundleContext aContext) throws Exception { 94 EngineActivator.context = null; 95 } 96 getExtensionsDirectories()97 public static File[] getExtensionsDirectories() { 98 List<File> files = new ArrayList<>(0); 99 if (EXTENSIONS != null) { 100 String[] locationToCheck = EXTENSIONS.split(","); //$NON-NLS-1$ 101 for (String location : locationToCheck) { 102 try { 103 files.addAll(getInfoFilesFromLocation(location)); 104 } catch (FileNotFoundException e) { 105 LogHelper.log(new Status(IStatus.ERROR, ID, NLS.bind(Messages.EngineActivator_0, location), e)); 106 } catch (IOException e) { 107 LogHelper.log(new Status(IStatus.ERROR, ID, NLS.bind(Messages.EngineActivator_0, location), e)); 108 } catch (URISyntaxException e) { 109 LogHelper.log(new Status(IStatus.ERROR, ID, NLS.bind(Messages.EngineActivator_0, location), e)); 110 } 111 } 112 } 113 return files.toArray(new File[files.size()]); 114 } 115 116 // This method must match the implementation in the SimpleConfiguratorUtils with the only difference that 117 // parent folder of the metadata is returned. getInfoFilesFromLocation(String locationToCheck)118 private static ArrayList<File> getInfoFilesFromLocation(String locationToCheck) throws IOException, FileNotFoundException, URISyntaxException { 119 ArrayList<File> result = new ArrayList<>(1); 120 121 File extensionsLocation = new File(locationToCheck); 122 123 if (extensionsLocation.exists() && extensionsLocation.isDirectory()) { 124 //extension location contains extensions 125 File[] extensions = extensionsLocation.listFiles(); 126 for (File extension : extensions) { 127 if (extension.isFile() && extension.getName().endsWith(LINK_FILE_EXTENSION)) { 128 Properties link = new Properties(); 129 link.load(new FileInputStream(extension)); 130 String newInfoName = link.getProperty(LINK_KEY); 131 URI newInfoURI = new URI(newInfoName); 132 File newInfoFile = null; 133 if (newInfoURI.isAbsolute()) { 134 newInfoFile = new File(newInfoName); 135 } else { 136 newInfoFile = new File(extension.getParentFile(), newInfoName); 137 } 138 if (newInfoFile.exists()) { 139 extension = newInfoFile.getParentFile(); 140 } 141 } 142 143 if (extension.isDirectory()) { 144 if (Files.isWritable(extension.toPath())) { 145 synchronized (reportedExtensions) { 146 if (!reportedExtensions.contains(extension)) { 147 reportedExtensions.add(extension); 148 LogHelper.log(new Status(IStatus.ERROR, ID, NLS.bind(Messages.EngineActivator_1, extension))); 149 } 150 } 151 continue; 152 } 153 File[] listFiles = extension.listFiles(); 154 // new magic - multiple info files, f.e. 155 // egit.info (git feature) 156 // cdt.link (properties file containing link=path) to other info file 157 for (File file : listFiles) { 158 //if it is a info file - load it 159 if (file.getName().endsWith(".info")) { //$NON-NLS-1$ 160 result.add(extension); 161 } 162 // if it is a link - dereference it 163 } 164 } else { 165 synchronized (reportedExtensions) { 166 if (!reportedExtensions.contains(extension)) { 167 reportedExtensions.add(extension); 168 LogHelper.log(new Status(IStatus.WARNING, ID, NLS.bind(Messages.EngineActivator_3, extension))); 169 } 170 } 171 } 172 } 173 } 174 return result; 175 } 176 } 177