/*******************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*
* Contributors:
* Lorenzo Bettini - https://bugs.eclipse.org/bugs/show_bug.cgi?id=428301
******************************************************************************/
package org.eclipse.buckminster.rmap.pde.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.buckminster.model.common.CommonFactory;
import org.eclipse.buckminster.model.common.ComponentIdentifier;
import org.eclipse.buckminster.rmap.pde.Messages;
import org.eclipse.buckminster.runtime.Buckminster;
import org.eclipse.buckminster.runtime.Logger;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.build.IFetchFactory;
import org.eclipse.pde.internal.build.FetchTaskFactoriesRegistry;
import static org.eclipse.buckminster.core.helpers.MapUtils.*;
/**
* @author Thomas Hallgren
*/
@SuppressWarnings("restriction")
public class MapFile {
private static final Pattern pattern = Pattern.compile("^" //$NON-NLS-1$
+ "\\s*([^@=,\\s]+)\\s*@" // The type, i.e. bundle, feature, plugin, or fragment //$NON-NLS-1$
+ "\\s*([^@,=\\s]+)\\s*" // Element ID //$NON-NLS-1$
+ "(?:,\\s*([^@,=\\s]+)\\s*)?=" // Optional version //$NON-NLS-1$
+ "(?:\\s*([A-Za-z_][A-Za-z0-9_-]*)\\s*,)?\\s*" // Optional fetch type specifier (default is CVS) //$NON-NLS-1$
+ "\\s*([^\\s]+)\\s*$"); // Fetch type specific field //$NON-NLS-1$
private static FetchTaskFactoriesRegistry fetchTaskFactories;
public static void parse(InputStream inputStream, String streamName, Map<String, String> properties, List<MapFileEntry> receivingList)
throws IOException {
Logger logger = Buckminster.getLogger();
if (fetchTaskFactories == null)
fetchTaskFactories = new FetchTaskFactoriesRegistry();
BufferedReader input = new BufferedReader(new InputStreamReader(inputStream));
String line;
nextLine: while ((line = input.readLine()) != null) {
// find first non-whitespace character on the line
int len = line.length();
int idx;
for (idx = 0; idx < len; ++idx) {
char c = line.charAt(idx);
if (Character.isWhitespace(c))
continue;
if (c == '!' || c == '#')
//
// Comment
//
continue nextLine;
break;
}
if (idx == len)
// Just whitespace
continue;
Matcher m = pattern.matcher(line);
if (!m.matches())
continue;
String fetchType = m.group(4);
String fetchTypeSpecific = m.group(5);
if (fetchType == null)
fetchType = "CVS"; //$NON-NLS-1$
else if (fetchType.equals("COPY")) //$NON-NLS-1$
{
logger.warning(NLS.bind(Messages.fetch_type_COPY_not_supported_map_0, streamName));
continue;
}
IFetchFactory ff = fetchTaskFactories.getFactory(fetchType);
if (ff == null) {
// Assume that the fetchType that we encountered is part of the
// fetchTypeSpecific string and that the real fetchType is CVS.
//
fetchTypeSpecific = fetchType + ',' + fetchTypeSpecific;
fetchType = "CVS"; //$NON-NLS-1$
ff = fetchTaskFactories.getFactory(fetchType);
if (ff == null) {
logger.warning(NLS.bind(Messages.no_factory_found_for_0_in_PDEmap_1, fetchType, streamName));
continue;
}
}
String type = m.group(1);
String ctypeId;
if ("plugin".equals(type) || "bundle".equals(type) || "fragment".equals(type)) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
ctypeId = "osgi.bundle";
else if ("feature".equals(type)) //$NON-NLS-1$
ctypeId = "eclipse.feature";
else {
// We don't recognize this type
//
logger.warning(NLS.bind(Messages.unrecognized_component_type_0_in_PDEmap_1, type, streamName));
continue;
}
String vstr = m.group(3);
Version version;
try {
version = vstr == null ? null : Version.parseVersion(vstr);
} catch (IllegalArgumentException e) {
// Version is corrupt. Skip this line
//
logger.warning(NLS.bind(Messages.badly_formatted_version_0_in_PDEmap_1, vstr, streamName));
continue;
}
String identifier = m.group(2);
Map<String, Object> props = new HashMap<String, Object>();
try {
ff.parseMapFileEntry(fetchTypeSpecific, null, props);
String tag = getString(props, IFetchFactory.KEY_ELEMENT_TAG);
if (tag != null && tag.length() > 2 && tag.charAt(0) == '@' && tag.charAt(tag.length() - 1) == '@') {
String tagKey = tag.substring(1, tag.length() - 1);
tag = properties.get(tagKey);
if (tag == null)
props.remove(IFetchFactory.KEY_ELEMENT_TAG);
else
props.put(IFetchFactory.KEY_ELEMENT_TAG, tag);
}
} catch (Exception e) {
logger.warning(NLS.bind(Messages.fetch_factory_0_unable_to_parse_1_in_PDEmap_2, new Object[] { fetchType, fetchTypeSpecific,
streamName }));
continue;
}
String readerTypeID = fetchType.toLowerCase(Locale.ENGLISH);
if ("get".equals(readerTypeID)) //$NON-NLS-1$
{
readerTypeID = "url"; //$NON-NLS-1$
// Extract a more exact version from the file name if possible
//
String src = getString(props, "src"); //$NON-NLS-1$
if (src.endsWith(".jar") || src.endsWith(".zip")) //$NON-NLS-1$ //$NON-NLS-2$
{
int lastSlash = src.lastIndexOf('/');
if (lastSlash < 0)
lastSlash = 0;
String vcName = src.substring(lastSlash + 1, src.length() - 4);
if (vcName.startsWith(identifier + '_')) {
try {
version = Version.parseVersion(vcName.substring(identifier.length() + 1));
} catch (IllegalArgumentException e) {
// Ignore. For some reason this version was not a
// valid OSGi version
}
}
}
} else if (readerTypeID.equals("p2iu")) //$NON-NLS-1$
readerTypeID = "p2"; //$NON-NLS-1$
ComponentIdentifier cid = CommonFactory.eINSTANCE.createComponentIdentifier();
cid.setId(identifier);
cid.setType(ctypeId);
cid.setVersion(version);
receivingList.add(new MapFileEntry(cid, readerTypeID, props));
}
}
}