blob: 86e6af03d26624398cf9787ac20168229b32a12d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 IBM Corporation 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:
* Boris Bokowski, IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.pde.internal.webui;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.*;
import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
import org.eclipse.emf.ecore.resource.*;
import org.eclipse.emf.ecore.resource.Resource.Factory;
import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.ifeature.IFeature;
import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
import org.osgi.framework.Version;
public class PDEServlet extends HttpServlet {
private static final long serialVersionUID = -5263759597889185038L;
private IWorkspace workspace;
private static String sessionID;
private synchronized IWorkspace getWorkspace() {
if (workspace == null) {
// enable auto-refresh:
new InstanceScope().getNode(ResourcesPlugin.PI_RESOURCES)
.putBoolean(ResourcesPlugin.PREF_AUTO_REFRESH, true);
workspace = ResourcesPlugin.getWorkspace();
}
return workspace;
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (!isAuthenticated(req)) {
resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
String pathInfo = req.getPathInfo();
if (pathInfo.startsWith("/site/")) {
String wsPath = pathInfo.substring("/site".length());
IResource resource = getWorkspace().getRoot().findMember(
new Path(wsPath));
if (resource.getType() != IResource.FILE) {
resp.setStatus(405);
return;
}
InputStream is = req.getInputStream();
int BUFFER_SIZE = 8192;
byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream os = new ByteArrayOutputStream();
int numRead = 0;
while ((numRead = is.read(buffer)) > 0) {
os.write(buffer, 0, numRead);
}
String jsonString = new String(os.toByteArray(), "ISO-8859-1");
Object json = JSONUtil.read(jsonString);
// System.out.println(json);
URI siteEcoreURI = URI.createPlatformPluginURI("/org.eclipse.e4.pde.webui/model/Site.ecore", true);
ResourceSet resourceSet = createResourceSet(siteEcoreURI);
EPackage ePackage = resourceSet.getPackageRegistry().getEPackage("platform:/plugin/org.eclipse.e4.pde.site.model/site.xsd");
Resource.Factory factory = (Factory) resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().get(Resource.Factory.Registry.DEFAULT_EXTENSION);
URI uri = URI.createPlatformResourceURI(resource.getFullPath()
.toString(), true);
Resource r = factory.createResource(uri);
EClass documentRootClass = (EClass) ePackage.getEClassifier("DocumentRoot");
EObject documentRoot = ePackage.getEFactoryInstance().create(documentRootClass);
EClass siteClass = (EClass) ePackage.getEClassifier("Site");
EObject site = ePackage.getEFactoryInstance().create(siteClass);
fill(site, (HashMap) json, ePackage.getEFactoryInstance());
documentRoot.eSet(documentRootClass.getEStructuralFeature("site"), site);
r.getContents().add(documentRoot);
OutputStream outputStream = resourceSet.getURIConverter().createOutputStream(uri);
r.save(outputStream, new HashMap());
outputStream.close();
}
}
private void fill(EObject eObject, HashMap json, EFactory eFactory) {
for(Iterator it = json.entrySet().iterator(); it.hasNext(); ) {
Entry entry = (Entry) it.next();
EStructuralFeature feature = eObject.eClass().getEStructuralFeature((String) entry.getKey());
if (entry.getValue() instanceof Collection) {
Collection targetCollection = (Collection) eObject.eGet(feature);
Collection sourceCollection = (Collection) entry.getValue();
for (Iterator it2 = sourceCollection.iterator(); it2
.hasNext();) {
Object element = it2.next();
EClass elementClass = (EClass) feature.getEType();
EObject targetElement = eFactory.create(elementClass);
fill(targetElement, (HashMap) element, eFactory);
targetCollection.add(targetElement);
}
} else if (entry.getValue() instanceof Map) {
EClass elementClass = (EClass) feature.getEType();
EObject targetElement = eFactory.create(elementClass);
fill(targetElement, (HashMap) entry.getValue(), eFactory);
eObject.eSet(feature, targetElement);
} else if (entry.getValue() instanceof String) {
eObject.eSet(feature, entry.getValue());
} else if (entry.getValue() != null) {
throw new RuntimeException("unsupported: " + entry.getValue());
}
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
String pathInfo = req.getPathInfo();
if (pathInfo.startsWith("/login")) {
if ("e4".equals(req.getParameter("username"))) {
if ("e4".equals(req.getParameter("password"))) {
resp.addCookie(new Cookie("org.eclipse.e4.pde.auth", getSessionId()));
try {
resp.sendRedirect(req.getParameter("nextURL"));
} catch (IOException e) {
e.printStackTrace();
}
return;
}
}
}
try {
resp.sendRedirect("/pde/login?nextURL=" + URLEncoder.encode(req.getParameter("nextURL"), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String pathInfo = req.getPathInfo();
if (pathInfo.startsWith("/login")) {
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("text/html; charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.append("<html>");
writer.append("<head>");
writer.append("<title>Please Log In</title>");
writer.append("</head>");
writer.append("<body>");
writer.append("<form method='post' action='/pde/login'>");
writer.append("username: ");
writer.append("<input type='text' name='username' />");
writer.append("<br />");
writer.append("password: ");
writer.append("<input type='password' name='password' />");
writer.append("<br />");
writer.append("<input type='submit' value='Login' />");
writer.append("<input type='hidden' name='nextURL' value='" + req.getParameter("nextURL") + "' />");
writer.append("</form>");
if (Activator.DEBUG) {
writer.append("<script type='text/javascript' src='/listCookies.js'></script>");
}
writer.append("</body>");
writer.append("</html>");
return;
}
if (!isAuthenticated(req)) {
resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
if (pathInfo.startsWith("/features/")) {
IFeatureModel[] allModels = PDECore.getDefault().getFeatureModelManager().getModels();
Arrays.sort(allModels, new Comparator() {
public int compare(Object arg0, Object arg1) {
IFeature f0 = ((IFeatureModel)arg0).getFeature();
IFeature f1 = ((IFeatureModel)arg1).getFeature();
return f0.getId().compareTo(f1.getId());
}
});
List features = new ArrayList(allModels.length);
for (int i = 0; i < allModels.length; i++) {
IFeature feature = allModels[i].getFeature();
Map featureJSON = new HashMap();
featureJSON.put("feature", null);
featureJSON.put("id", feature.getId());
featureJSON.put("url", "features/" + feature.getId() + "_" + new Version(feature.getVersion()).toString() + ".jar");
featureJSON.put("version", feature.getVersion());
features.add(featureJSON);
}
resp.setStatus(200);
resp.setContentType("application/json; charset=UTF-8");
Map jsonResult = new HashMap();
jsonResult.put("identifier", "id");
jsonResult.put("label", "id");
jsonResult.put("items", features);
PrintWriter writer = resp.getWriter();
writer.write("/*");
writer.write(JSONUtil.write(jsonResult));
writer.write("*/");
return;
} else if (pathInfo.startsWith("/site/")) {
String wsPath = pathInfo.substring("/site".length());
IResource resource = getWorkspace().getRoot().findMember(
new Path(wsPath));
if (resource.getType() != IResource.FILE) {
resp.setStatus(405);
return;
}
PrintWriter writer = resp.getWriter();
try {
URI siteEcoreURI = URI.createPlatformPluginURI("/org.eclipse.e4.pde.webui/model/Site.ecore", true);
ResourceSet resourceSet = createResourceSet(siteEcoreURI);
URI uri = URI.createPlatformResourceURI(resource.getFullPath()
.toString(), true);
Resource r = resourceSet.getResource(uri, true);
EObject eRootObject = (EObject) r.getContents().get(0);
resp.setStatus(200);
resp.setContentType("application/json; charset=UTF-8");
writer.write("/*");
writer.write(EMFJSONUtil.write((EObject) eRootObject.eContents().get(0)));
writer.write("*/");
return;
} catch (Exception e) {
e.printStackTrace(writer);
resp.setStatus(500);
return;
}
}
}
private boolean isAuthenticated(HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("org.eclipse.e4.pde.auth")) {
if (cookies[i].getValue().equals(getSessionId())) {
return true;
}
}
}
}
return false;
}
public static String getSessionId() {
if (sessionID == null) {
sessionID = UUID.randomUUID().toString();
}
return sessionID;
}
private ResourceSet createResourceSet(URI siteEcoreURI) {
ResourceSet resourceSet = new ResourceSetImpl();
Resource ecoreResource = resourceSet.getResource(siteEcoreURI, true);
final BasicExtendedMetaData extendedMetaData = new BasicExtendedMetaData(new EPackageRegistryImpl(EPackage.Registry.INSTANCE));
EPackage ecorePackage = (EPackage) ecoreResource.getContents().get(0);
extendedMetaData.putPackage(null, ecorePackage);
// Register the appropriate resource factory to handle all file extensions.
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
(Resource.Factory.Registry.DEFAULT_EXTENSION,
new ResourceFactoryImpl(){
public Resource createResource(URI uri) {
XMLResource result = new XMLResourceImpl(uri);
result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
result.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE);
return result;
}
});
// Register the package to ensure it is available during loading.
//
resourceSet.getPackageRegistry().put
(ecorePackage.getNsURI(), ecorePackage);
return resourceSet;
}
}