/******************************************************************************* * Copyright (c) 2015 Red Hat, 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: * Red Hat Inc. - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.thym.core.engine.internal.cordova; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Set; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpParams; 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.eclipse.thym.core.HybridCore; import org.eclipse.thym.core.engine.AbstractEngineRepoProvider; import org.eclipse.thym.core.extensions.PlatformSupport; import org.eclipse.thym.core.internal.util.HttpUtil; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.stream.JsonReader; public class NpmBasedEngineRepoProvider extends AbstractEngineRepoProvider{ private static final String NPM_URL ="https://registry.npmjs.org/cordova-{0}"; private InputStream getRemoteJSonStream(String url) throws IOException{ try { // SSLSocketFactory to patch HTTPClient's that are earlier than 4.3.2 // to enable SNI support. SSLSocketFactory factory = new SSLSocketFactory(SSLContext.getDefault()){ @Override public Socket createSocket() throws IOException { return SocketFactory.getDefault().createSocket(); } @Override public Socket createSocket(HttpParams params) throws IOException { return SocketFactory.getDefault().createSocket(); } }; DefaultHttpClient client = new DefaultHttpClient(); HttpUtil.setupProxy(client); client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, factory)); HttpGet get = new HttpGet(url); HttpResponse response = client.execute(get); HttpEntity entity = response.getEntity(); return entity.getContent(); } catch (NoSuchAlgorithmException e) { HybridCore.log(IStatus.ERROR, "Error creating the SSL Factory ", e); } return null; } @Override public List<DownloadableCordovaEngine> getEngines() throws CoreException { List<PlatformSupport> platforms = HybridCore.getPlatformSupports(); List<DownloadableCordovaEngine> allEngines = new ArrayList<DownloadableCordovaEngine>(); for (PlatformSupport support : platforms) { List<DownloadableCordovaEngine> platEngines = getPlatformEngines(support.getPlatformId()); if(platEngines != null && !platEngines.isEmpty()){ allEngines.addAll(platEngines); } } return allEngines; } private List<DownloadableCordovaEngine> getPlatformEngines(String platformId) throws CoreException{ try { InputStream stream = getRemoteJSonStream(NLS.bind(NPM_URL, platformId)); if (stream != null) { return parseEngines(stream, platformId); }else{ return null; } } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, HybridCore.PLUGIN_ID, NLS.bind( "Could not retrieve and parse downloadable platform information for ({0})", platformId),e)); } } private List<DownloadableCordovaEngine> parseEngines(InputStream stream, String platformId) throws IOException{ List<DownloadableCordovaEngine> engines = new ArrayList<DownloadableCordovaEngine>(); JsonReader reader = null; try { reader = new JsonReader(new InputStreamReader(stream)); JsonParser parser = new JsonParser(); final JsonObject root = (JsonObject) parser.parse(reader); final JsonElement element = root.get("versions"); final JsonObject topVersions = element.getAsJsonObject(); final Set<Entry<String, JsonElement>> versions = topVersions.entrySet(); for (Iterator<Entry<String, JsonElement>> iterator = versions.iterator(); iterator.hasNext();) { Entry<String, JsonElement> entry = iterator.next(); JsonObject v = entry.getValue().getAsJsonObject(); DownloadableCordovaEngine engine = new DownloadableCordovaEngine(); engine.setVersion(v.get("version").getAsString()); engine.setPlatformId(platformId); JsonObject dist = v.get("dist").getAsJsonObject(); engine.setDownloadURL(dist.get("tarball").getAsString()); engines.add(engine); } } finally { if (reader != null) { reader.close(); } } return engines; } }