/*******************************************************************************
* Copyright (c) 2012 OpenLegacy 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:
* OpenLegacy Inc. - initial API and implementation
*******************************************************************************/
package org.openlegacy.designtime.newproject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openlegacy.designtime.PreferencesConstants;
import org.openlegacy.designtime.newproject.model.ProjectProvider;
import org.openlegacy.designtime.newproject.model.ProjectTheme;
import org.openlegacy.designtime.newproject.model.ProjectType;
import org.openlegacy.exceptions.OpenLegacyException;
import org.openlegacy.utils.XmlSerializationUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Retrieves metadata
*
*/
public class NewProjectMetadataRetriever {
private final static Log logger = LogFactory.getLog(NewProjectMetadataRetriever.class);
@XmlRootElement(name = "project-types")
private static class ProjectTypeStore {
private List<ProjectType> projectTypes;
@XmlElements({ @XmlElement(name = "project-type", type = ProjectType.class) })
public List<ProjectType> getProjectTypes() {
return projectTypes;
}
@SuppressWarnings("unused")
public void setProjectTypes(List<ProjectType> projectTypes) {
this.projectTypes = projectTypes;
}
}
@XmlRootElement(name = "providers")
private static class ProjectProviderStore {
private List<ProjectProvider> providers;
@XmlElements({ @XmlElement(name = "provider", type = ProjectProvider.class) })
public List<ProjectProvider> getProviders() {
return providers;
}
@SuppressWarnings("unused")
public void setProviders(List<ProjectProvider> providers) {
this.providers = providers;
}
}
@XmlRootElement(name = "themes")
private static class ProjectThemeStore {
private List<ProjectTheme> themes;
@XmlElements({ @XmlElement(name = "theme", type = ProjectTheme.class) })
public List<ProjectTheme> getThemes() {
return themes;
}
@SuppressWarnings("unused")
public void setThemes(List<ProjectTheme> themes) {
this.themes = themes;
}
}
private static final String RESOURCE_XML_PATH = "/templates/xml";
private static final String RESOURCE_THEME_IMAGES_PATH = "/templates/theme-images";
private static final String ONLINE_XML_FOLDER = "xml";
private static final String ONLINE_THEME_IMAGES_FOLDER = "theme-images";
private ProjectTypeStore projectTypeStore = null;
private ProjectProviderStore projectProviderStore = null;
private ProjectThemeStore projectThemeStore = null;
private String templatesUrl = null;
private boolean isRetrievedOnline = false;
private ITemplateFetcher templateFetcher;
public NewProjectMetadataRetriever(String templatesUrl) {
setTemplatesUrl(templatesUrl);
}
public void retrieveMetadata() throws OpenLegacyException, JAXBException, IOException {
try {
this.fetchStoresOnline();
this.isRetrievedOnline = true;
this.templateFetcher = new OnlineTemplateFetcher(this.templatesUrl);
} catch (Exception e) {
logger.warn("Cannot retrieve metadata online", e);
this.fetchStores();
this.isRetrievedOnline = false;
this.templateFetcher = new ResourceTemplateFetcher();
}
}
public List<ProjectType> getProjectTypes() {
if (this.projectTypeStore == null) {
return new ArrayList<ProjectType>();
}
return this.projectTypeStore.getProjectTypes();
}
public List<ProjectProvider> getProviders() {
if (this.projectProviderStore == null) {
return new ArrayList<ProjectProvider>();
}
return this.projectProviderStore.getProviders();
}
public List<ProjectTheme> getThemes() {
if (this.projectThemeStore == null) {
return new ArrayList<ProjectTheme>();
}
return this.projectThemeStore.getThemes();
}
public void setTemplatesUrl(String templatesUrl) {
this.templatesUrl = templatesUrl;
}
public boolean isRetrievedOnline() {
return isRetrievedOnline;
}
public String getTemplatesUrl() {
return this.templatesUrl;
}
public ITemplateFetcher getTemplateFetcher() {
return templateFetcher;
}
private void fetchStoresOnline() throws IOException, JAXBException, OpenLegacyException {
this.projectTypeStore = this.fetchStoreOnline(ProjectTypeStore.class, PreferencesConstants.PROJECT_TYPES_FILENAME);
this.projectProviderStore = this.fetchStoreOnline(ProjectProviderStore.class,
PreferencesConstants.PROJECT_PROVIDERS_FILENAME);
this.projectThemeStore = this.fetchStoreOnline(ProjectThemeStore.class, PreferencesConstants.PROJECT_THEMES_FILENAME);
this.fetchThemeImagesOnline();
if ((this.projectTypeStore.getProjectTypes() == null) || (this.projectProviderStore.getProviders() == null)
|| (this.projectThemeStore.getThemes() == null)) {
throw new OpenLegacyException("Cannot retrieve metadata online from " + this.templatesUrl);
}
}
private void fetchStores() throws JAXBException, IOException, OpenLegacyException {
this.projectTypeStore = this.fetchStore(ProjectTypeStore.class, PreferencesConstants.PROJECT_TYPES_FILENAME);
this.projectProviderStore = this.fetchStore(ProjectProviderStore.class, PreferencesConstants.PROJECT_PROVIDERS_FILENAME);
this.projectThemeStore = this.fetchStore(ProjectThemeStore.class, PreferencesConstants.PROJECT_THEMES_FILENAME);
this.fetchThemeImages();
if ((this.projectTypeStore.getProjectTypes() == null) || (this.projectProviderStore.getProviders() == null)
|| (this.projectThemeStore.getThemes() == null)) {
throw new OpenLegacyException("Cannot retrieve metadata from resources");
}
}
private <P> P fetchStoreOnline(Class<P> rootClass, String filename) throws IOException, JAXBException {
InputStream in = getUrlConnectionInputStream(MessageFormat.format("{0}/{1}/{2}", this.templatesUrl, ONLINE_XML_FOLDER,
filename));
P store = XmlSerializationUtil.deserialize(rootClass, in);
in.close();
return store;
}
private byte[] fetchImageOnline(String imageFile) throws IOException {
InputStream in = getUrlConnectionInputStream(MessageFormat.format("{0}/{1}/{2}", this.templatesUrl,
ONLINE_THEME_IMAGES_FOLDER, imageFile));
return getImageData(in);
}
private void fetchThemeImagesOnline() throws IOException, NullPointerException {
for (ProjectTheme theme : this.projectThemeStore.getThemes()) {
theme.setImageData(this.fetchImageOnline(theme.getImageFile()));
}
}
private <P> P fetchStore(Class<P> rootClass, String filename) throws JAXBException, IOException {
InputStream in = getClass().getResourceAsStream(MessageFormat.format("{0}/{1}", RESOURCE_XML_PATH, filename));
P store = XmlSerializationUtil.deserialize(rootClass, in);
in.close();
return store;
}
private byte[] fetchImage(String imageFile) throws IOException {
InputStream in = getClass().getResourceAsStream(MessageFormat.format("{0}/{1}", RESOURCE_THEME_IMAGES_PATH, imageFile));
return getImageData(in);
}
private void fetchThemeImages() throws IOException, NullPointerException {
for (ProjectTheme theme : this.projectThemeStore.getThemes()) {
theme.setImageData(this.fetchImage(theme.getImageFile()));
}
}
private static InputStream getUrlConnectionInputStream(String urlPath) throws IOException {
URL url = new URL(urlPath);
URLConnection con = url.openConnection();
con.setDoInput(true);
con.setDoOutput(false);
con.connect();
return con.getInputStream();
}
private static byte[] getImageData(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int n = 0;
while ((n = in.read(buff)) != -1) {
out.write(buff, 0, n);
}
out.close();
in.close();
return out.toByteArray();
}
}