/************************************************************************************* * Copyright (c) 2008-2014 Red Hat, Inc. and others. * 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: * JBoss by Red Hat - Initial implementation. ************************************************************************************/ package org.jboss.tools.arquillian.core.internal.container; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.Collections; import java.util.List; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.Job; import org.jboss.forge.arquillian.container.Container; import org.jboss.tools.arquillian.core.ArquillianCoreActivator; import org.jboss.tools.foundation.core.ecf.URLTransportUtility; import org.osgi.framework.Bundle; /** * * @author snjeza * */ public class ContainerParser { private static final String CONTAINERS_JSON = "https://raw.github.com/forge/plugin-arquillian/master/src/main/resources/containers.json"; //$NON-NLS-1$ private static final String PROTOCOL_FILE = "file"; //$NON-NLS-1$ private static final String PROTOCOL_PLATFORM = "platform"; //$NON-NLS-1$ private static List<Container> containers; /** * Refresh parser * */ public static void refresh() { containers = null; } /** * Returns list of containers * */ public static List<Container> getContainers() { if (containers != null) { return containers; } ObjectMapper objectMapper = new ObjectMapper(); // a workaround for JBIDE-19324 - Arquillian core freezes Eclipse startup boolean suspended = Job.getJobManager().isSuspended(); if (!suspended) { URL url = getUrl(); if (url != null) { try { containers = objectMapper.readValue(url, new TypeReference<List<Container>>() { }); } catch (Exception e) { ArquillianCoreActivator.log(e); } } } else { // we can't use Eclipse job framework because JobManager is suspended in this moment Thread refreshingThread = new Thread("Refreshing containers ...") { @Override public void run() { while (Job.getJobManager().isSuspended()) { try { sleep(1000); } catch (InterruptedException e) { // ignore } } refresh(); getContainers(); } }; refreshingThread.start(); } if (containers == null || containers.size() == 0) { try { File f = getFile(new URL(CONTAINERS_JSON)); URL url; if (f != null && f.isFile() && f.length() > 0) { url = f.toURL(); } else { url = getUrlFromBundle(); } containers = objectMapper.readValue(url, new TypeReference<List<Container>>() { }); return containers; } catch (Exception e) { ArquillianCoreActivator.log(e); } } if (containers == null) { return Collections.emptyList(); } return containers; } private static URL getUrl() { try { File f = getFile(new URL(CONTAINERS_JSON), "containers", "json", new NullProgressMonitor()); //$NON-NLS-1$ //$NON-NLS-2$ if (f == null || !f.exists()) { return getUrlFromBundle(); } else { return f.toURL(); } } catch (Exception e) { ArquillianCoreActivator.log(e); } return null; } private static URL getUrlFromBundle() { Bundle bundle = Platform.getBundle(ArquillianCoreActivator.PLUGIN_ID); if (bundle != null) { URL[] urls = FileLocator.findEntries(bundle, new Path( "/containers.json")); //$NON-NLS-1$ if (urls != null && urls.length > 0) { try { return FileLocator.resolve(urls[0]); } catch (IOException e) { ArquillianCoreActivator.log(e); } } } return null; } private static File getFile(URL url, String prefix, String suffix, IProgressMonitor monitor) { File file = null; if (PROTOCOL_FILE.equals(url.getProtocol()) || PROTOCOL_PLATFORM.equalsIgnoreCase(url.getProtocol())) { try { file = new File(new URI(url.toExternalForm())); } catch (Exception e) { file = new File(url.getFile()); } if (!file.exists()) return null; } else { try { if (monitor.isCanceled()) { return null; } long urlModified = -1; file = getFile(url); try { urlModified = new URLTransportUtility() .getLastModified(url); } catch (CoreException e) { if (file.exists()) { return file; } } if (file.exists()) { long modified = file.lastModified(); if (modified > 0 && urlModified == modified) { return file; } } boolean fileAlreadyExists = file.exists(); file.getParentFile().mkdirs(); if (monitor.isCanceled()) { return null; } BufferedOutputStream destination = new BufferedOutputStream( new FileOutputStream(file)); IStatus result = new URLTransportUtility().download(prefix, url.toExternalForm(), destination, monitor); if (!result.isOK()) { ArquillianCoreActivator.getDefault().getLog().log(result); if (!fileAlreadyExists && file.exists()) { file.delete(); } return null; } else { if (file.exists() && urlModified > 0) { file.setLastModified(urlModified); } } } catch (FileNotFoundException e) { ArquillianCoreActivator.log(e); return null; } } return file; } private static File getFile(URL url) { IPath location = ArquillianCoreActivator.getDefault().getStateLocation(); File root = location.toFile(); String urlFile = url.getFile(); File file = new File(root, urlFile); return file; } }