blob: 8877bd56fc7022f449aa9f03551ee214c8c1d920 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2010 Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sonatype, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.m2e.core.internal.archetype;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.apache.maven.archetype.ArchetypeManager;
import org.apache.maven.archetype.catalog.ArchetypeCatalog;
import org.apache.maven.archetype.catalog.io.xpp3.ArchetypeCatalogXpp3Reader;
import org.apache.maven.archetype.source.ArchetypeDataSource;
import org.apache.maven.archetype.source.ArchetypeDataSourceException;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.MavenPluginActivator;
import org.eclipse.m2e.core.internal.Messages;
/**
* Abstract ArchetypeCatalog factory
*/
public abstract class ArchetypeCatalogFactory {
private static final Logger log = LoggerFactory.getLogger(ArchetypeCatalogFactory.class);
private final String id;
private final String description;
private final boolean editable;
public ArchetypeCatalogFactory(String id, String description, boolean editable) {
this.id = id;
this.description = description;
this.editable = editable;
}
public String getId() {
return this.id;
}
public String getDescription() {
return this.description;
}
public boolean isEditable() {
return editable;
}
public abstract ArchetypeCatalog getArchetypeCatalog() throws CoreException;
public String toString() {
return getId();
}
protected ArchetypeManager getArchetyper() {
return MavenPluginActivator.getDefault().getArchetypeManager().getArchetyper();
}
/**
* Factory for Nexus Indexer ArchetypeCatalog
*/
public static class NexusIndexerCatalogFactory extends ArchetypeCatalogFactory {
public static final String ID = "nexusIndexer"; //$NON-NLS-1$
public NexusIndexerCatalogFactory() {
super(ID, Messages.ArchetypeCatalogFactory_indexer_catalog, false);
}
public ArchetypeCatalog getArchetypeCatalog() throws CoreException {
try {
ArchetypeDataSource source = MavenPluginActivator.getDefault().getIndexManager().getArchetypeCatalog();
return source.getArchetypeCatalog(new Properties());
} catch(ArchetypeDataSourceException ex) {
String msg = NLS.bind(Messages.ArchetypeCatalogFactory_error_missing_catalog, ex.getMessage());
log.error(msg, ex);
throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, -1, msg, ex));
}
}
}
/**
* Factory for internal ArchetypeCatalog
*/
public static class InternalCatalogFactory extends ArchetypeCatalogFactory {
public static final String ID = "internal"; //$NON-NLS-1$
public InternalCatalogFactory() {
super(ID, Messages.ArchetypeCatalogFactory_internal, false);
}
public ArchetypeCatalog getArchetypeCatalog() {
return getArchetyper().getInternalCatalog();
}
}
/**
* Factory for default local ArchetypeCatalog
*/
public static class DefaultLocalCatalogFactory extends ArchetypeCatalogFactory {
public static final String ID = "defaultLocal"; //$NON-NLS-1$
public DefaultLocalCatalogFactory() {
super(ID, Messages.ArchetypeCatalogFactory_default_local, false);
}
public ArchetypeCatalog getArchetypeCatalog() {
return getArchetyper().getDefaultLocalCatalog();
}
}
/**
* Factory for local ArchetypeCatalog
*/
public static class LocalCatalogFactory extends ArchetypeCatalogFactory {
public LocalCatalogFactory(String path, String description, boolean editable) {
super(path, description == null || description.trim().length() == 0
? NLS.bind(Messages.ArchetypeCatalogFactory_local, path) : description, editable);
}
public ArchetypeCatalog getArchetypeCatalog() throws CoreException {
ArchetypeCatalog catalog = getEmbeddedCatalog();
if(catalog == null) {
//local but not embedded catalog
catalog = getArchetyper().getLocalCatalog(getId());
}
return catalog;
}
private ArchetypeCatalog getEmbeddedCatalog() throws CoreException {
URL url = getEmbeddedUrl();
if(url == null) {
//Not an embedded catalog, nothing else to do
return null;
}
try (InputStream is = new BufferedInputStream(url.openStream())) {
return new ArchetypeCatalogXpp3Reader().read(is);
} catch(Exception ex) {
String msg = NLS.bind(Messages.ArchetypeCatalogFactory_error_missing_catalog, ex.getMessage());
log.error(msg, ex);
throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, -1, msg, ex));
}
}
private URL getEmbeddedUrl() {
String path = getId();
if(path != null && path.startsWith("bundleentry://")) {
try {
return new URL(path);
} catch(Exception ex) {
log.error(ex.getMessage(), ex);
}
}
return null;
}
}
/**
* Factory for remote ArchetypeCatalog
*/
public static class RemoteCatalogFactory extends ArchetypeCatalogFactory {
private String repositoryUrl = null;
public RemoteCatalogFactory(String url, String description, boolean editable) {
super(url, description == null || description.trim().length() == 0
? NLS.bind(Messages.ArchetypeCatalogFactory_remote, url) : description, editable);
repositoryUrl = parseCatalogUrl(url);
}
/**
* @param url
* @return
*/
private String parseCatalogUrl(String url) {
if(url == null) {
return null;
}
int length = url.length();
if(length > 1 && url.endsWith("/")) //$NON-NLS-1$
{
return url.substring(0, url.length() - 1);
}
int idx = url.lastIndexOf("/"); //$NON-NLS-1$
idx = (idx > 0) ? idx : 0;
if(url.lastIndexOf(".") >= idx) { //$NON-NLS-1$
//Assume last fragment of the url is a file, let's keep its parent folder
return url.substring(0, idx);
}
return url;
}
public ArchetypeCatalog getArchetypeCatalog() {
String url = getId();
int idx = url.lastIndexOf("/archetype-catalog.xml");
if(idx > -1) {
url = url.substring(0, idx);
}
final ArchetypeCatalog catalog = getArchetyper().getRemoteCatalog(url);
final String remoteUrl = url;
@SuppressWarnings("serial")
ArchetypeCatalog catalogWrapper = new ArchetypeCatalog() {
public void addArchetype(org.apache.maven.archetype.catalog.Archetype archetype) {
catalog.addArchetype(archetype);
}
@SuppressWarnings({"rawtypes", "unchecked"})
public List getArchetypes() {
List<org.apache.maven.archetype.catalog.Archetype> archetypes = new ArrayList<org.apache.maven.archetype.catalog.Archetype>(
catalog.getArchetypes());
for(org.apache.maven.archetype.catalog.Archetype arch : archetypes) {
if(arch.getRepository() == null || arch.getRepository().trim().isEmpty()) {
arch.setRepository(remoteUrl);
}
}
return archetypes;
}
public String getModelEncoding() {
return catalog.getModelEncoding();
}
public void removeArchetype(org.apache.maven.archetype.catalog.Archetype archetype) {
catalog.removeArchetype(archetype);
}
public void setModelEncoding(String modelEncoding) {
catalog.setModelEncoding(modelEncoding);
}
public void setArchetypes(List archetypes) {
catalog.setArchetypes(archetypes);
}
public String toString() {
return catalog.toString();
}
};
return catalogWrapper;
}
/**
* @return the url of the remote repository hosting the catalog
*/
public String getRepositoryUrl() {
return repositoryUrl;
}
}
}