/*
* Copyright 2009 NCHOVY
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krakenapps.pkg;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import org.krakenapps.api.BundleRepository;
import org.krakenapps.api.KeyStoreManager;
import org.krakenapps.api.Version;
public class MavenMetadata {
private BundleRepository repo;
private KeyStoreManager keyStoreManager;
private String groupId;
private String artifactId;
private Version release;
private Version latest;
private List<Version> versions;
private Date lastUpdated;
public MavenMetadata(BundleRepository repo, KeyStoreManager keyStoreManager, String groupId, String artifactId)
throws KeyManagementException, UnrecoverableKeyException, KeyStoreException, IOException {
this.repo = repo;
this.keyStoreManager = keyStoreManager;
this.groupId = groupId;
this.artifactId = artifactId;
refresh();
}
public void refresh() throws KeyManagementException, UnrecoverableKeyException, KeyStoreException, IOException {
if (this.repo.getUrl().getProtocol().equals("file"))
refresh("maven-metadata-local.xml");
else
refresh("maven-metadata.xml");
}
public void refresh(String metadataFilename) throws KeyManagementException, UnrecoverableKeyException,
KeyStoreException, IOException {
URL url = new URL(normalize(repo.getUrl())
+ String.format("%s/%s/%s", groupId.replace(".", "/"), artifactId, metadataFilename));
String metadata = download(repo, url);
String versioning = extract(metadata, "versioning");
if (versioning != null) {
String releaseStr = extract(versioning, "release");
if (releaseStr != null)
release = new Version(releaseStr);
else
release = null;
String latestStr = extract(versioning, "latest");
if (latestStr != null)
latest = new Version(latestStr);
else
latest = null;
String versionsStr = extract(versioning, "versions");
if (versionsStr != null) {
Matcher versionsMatcher = Pattern.compile("(?<=<version>).+?(?=</version>)", Pattern.DOTALL).matcher(
versionsStr);
versions = new ArrayList<Version>();
while (versionsMatcher.find())
versions.add(new Version(versionsMatcher.group()));
Collections.sort(versions, new VersionComparator());
} else
versions = null;
String lastUpdatedStr = extract(versioning, "lastUpdated");
if (lastUpdatedStr != null) {
try {
lastUpdated = new SimpleDateFormat("yyyyMMddHHmmss").parse(lastUpdatedStr);
} catch (ParseException e) {
}
} else
lastUpdated = null;
} else {
release = null;
latest = null;
versions = null;
lastUpdated = null;
}
}
private String download(BundleRepository repository, URL url) throws IOException, KeyStoreException,
KeyManagementException, UnrecoverableKeyException {
if (repository.isHttps() && keyStoreManager != null) { // https
try {
String trustStoreAlias = repository.getTrustStoreAlias();
String keyStoreAlias = repository.getKeyStoreAlias();
TrustManagerFactory tmf = keyStoreManager.getTrustManagerFactory(trustStoreAlias, "SunX509");
KeyManagerFactory kmf = keyStoreManager.getKeyManagerFactory(keyStoreAlias, "SunX509");
return new String(HttpWagon.download(url, tmf, kmf));
} catch (NoSuchAlgorithmException e) {
return null;
}
} else if (repository.isAuthRequired()) // http auth
return new String(HttpWagon.download(url, true, repository.getAccount(), repository.getPassword()));
else if (url.getProtocol().equals("file")) {
try {
File file = new File(url.toURI());
long length = file.length();
FileInputStream stream = new FileInputStream(file);
byte[] b = new byte[(int) length];
stream.read(b);
return new String(b);
} catch (URISyntaxException e) {
e.printStackTrace();
return "";
}
} else
// plain http
return new String(HttpWagon.download(url));
}
private URL normalize(URL url) {
String urlStr = url.toString();
if (urlStr.lastIndexOf('/') == urlStr.length() - 1)
return url;
try {
return new URL(url + "/");
} catch (MalformedURLException e) {
return null; // ignore
}
}
private String extract(String orig, String prefix) {
String regex = String.format("(?<=<%s>).+?(?=</%s>)", prefix, prefix);
Matcher matcher = Pattern.compile(regex, Pattern.DOTALL).matcher(orig);
if (matcher.find())
return matcher.group();
else
return null;
}
private class VersionComparator implements Comparator<Version> {
@Override
public int compare(Version o1, Version o2) {
String[] v1 = o1.toString().split("\\.");
String[] v2 = o2.toString().split("\\.");
for (int i = 0; i < Math.min(v1.length, v2.length); i++) {
try {
int i1 = Integer.parseInt(v1[i]);
int i2 = Integer.parseInt(v2[i]);
if (i1 != i2)
return (i2 - i1);
} catch (NumberFormatException e) {
if (!v1[i].equals(v2[i]))
return v2[i].compareTo(v1[i]);
}
}
return (v2.length - v1.length);
}
}
public BundleRepository getRepo() {
return repo;
}
public String getGroupId() {
return groupId;
}
public String getArtifactId() {
return artifactId;
}
public Version getRelease() {
return release;
}
public Version getLatest() {
return latest;
}
public List<Version> getVersions() {
return versions;
}
public Date getLastUpdated() {
return lastUpdated;
}
}