blob: 35235cafd37361e61548ad8db45df7dc00f22f21 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.update.internal.search;
import java.io.*;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.core.*;
import org.eclipse.update.search.IUpdateSiteAdapter;
/**
*
* This class opens connection to the update map resource
* and parses the file to load update URL mappings.
* These mappings are used to redirect new updates search
* when the redirection pattern matches.
*/
public class UpdateMap {
private static final String KEY_MAP = "url-map";
private static final String KEY_FALLBACK = "try-embedded";
private boolean fallbackAllowed = true;
private static class MapSite implements IUpdateSiteAdapter {
private URL url;
public MapSite(URL url) {
this.url = url;
}
public String getLabel() {
return url.toString();
}
public URL getURL() {
return url;
}
}
private static class UpdateMapEntry {
private IUpdateSiteAdapter site;
private String pattern;
public UpdateMapEntry(String pattern, URL url) {
this.pattern = pattern;
this.site = new MapSite(url);
}
public IUpdateSiteAdapter getSite() {
return site;
}
public boolean matches(String id) {
return id.startsWith(pattern);
}
public String getPattern() {
return pattern;
}
}
private ArrayList entries;
private IUpdateSiteAdapter defaultSite;
private boolean loaded = false;
public UpdateMap() {
entries = new ArrayList();
}
public void load(URL mapFile, IProgressMonitor monitor)
throws CoreException {
InputStream mapStream = null;
try {
Response response = UpdateCore.getPlugin().get(mapFile);
UpdateManagerUtils.checkConnectionResult(response, mapFile);
mapStream = response.getInputStream(monitor);
// the stream can be null if the user cancels the connection
if (mapStream == null)
return;
Properties mappings = new Properties();
mappings.load(mapStream);
processMappings(mappings);
loaded = true;
} catch (IOException e) {
throw Utilities.newCoreException(
Policy.bind(
"SiteURLFactory.UnableToAccessSiteStream",
mapFile == null ? "" : mapFile.toExternalForm()),
ISite.SITE_ACCESS_EXCEPTION,
e);
} finally {
if (mapStream != null) {
try {
mapStream.close();
} catch (IOException e) {
}
}
}
}
public boolean isLoaded() {
return loaded;
}
private void processMappings(Properties mappings) {
if (entries.isEmpty() == false)
entries.clear();
for (Enumeration enum = mappings.keys(); enum.hasMoreElements();) {
String key = (String) enum.nextElement();
if (key.startsWith(KEY_MAP)) {
String pattern = key.substring(7);
String value = (String) mappings.get(key);
if (value != null && value.length() > 0) {
String decodedValue = URLDecoder.decode(value);
try {
URL url = new URL(decodedValue);
addEntry(pattern, url);
} catch (MalformedURLException e) {
}
}
}
}
String fallback = mappings.getProperty(KEY_FALLBACK, "true");
fallbackAllowed = fallback.equalsIgnoreCase("true");
}
private void addEntry(String pattern, URL url) {
if (pattern.equalsIgnoreCase("*"))
defaultSite = new MapSite(url);
else
entries.add(new UpdateMapEntry(pattern, url));
}
/*
* Given the feature ID, returns the mapped update URL if
* found in the mappings. This URL will be used INSTEAD of
* the update URL encoded in the feature itself during the
* new update search.
* <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
* the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
*/
public IUpdateSiteAdapter getMappedSite(String id) {
UpdateMapEntry lastEntry = null;
for (int i = 0; i < entries.size(); i++) {
UpdateMapEntry entry = (UpdateMapEntry) entries.get(i);
if (entry.matches(id)) {
if (lastEntry == null)
lastEntry = entry;
else {
// Choose the match with longer pattern.
// For example, if two matches are found:
// 'org.eclipse' and 'org.eclipse.platform',
// pick 'org.eclipse.platform'.
String pattern = entry.getPattern();
String lastPattern = lastEntry.getPattern();
if (pattern.length() > lastPattern.length())
lastEntry = entry;
}
}
}
if (lastEntry != null)
return lastEntry.getSite();
else
return defaultSite;
}
public boolean isFallbackAllowed() {
return fallbackAllowed;
}
}