/** * <copyright> * * Copyright (c) 2011 Springsite BV (The Netherlands) 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: * Martin Taal - Initial API and implementation * * </copyright> * * $Id: DataModelBrowserServlet.java,v 1.4 2011/09/14 15:35:48 mtaal Exp $ */ package org.eclipse.emf.texo.server.web; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.texo.component.ComponentProvider; import org.eclipse.emf.texo.model.ModelPackage; import org.eclipse.emf.texo.server.service.ServiceModelPackageRegistry; import org.eclipse.emf.texo.server.web.WebServiceHandler.XSLTServiceContextResultProcessor; import org.eclipse.emf.texo.utils.ModelUtils; /** * The data model browser allows you to browse/navigate through the model using standard web service calls. * * An extra function provided by the model browser is to make it possible to generate test data for a certain epackage. * * @author <a href="mtaal@elver.org">Martin Taal</a> */ public class DataModelBrowserServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final String ACTION_PARAMETER = "action"; //$NON-NLS-1$ private static final String GENERATE_TEST_DATA_ACTION = "testData".toLowerCase(); //$NON-NLS-1$ private static final String TEMPLATE_PARAMETER = "template"; //$NON-NLS-1$ private static final String TYPE_PARAMETER = "type"; //$NON-NLS-1$ private static final String TYPE_PARAMETER_XML = "xml"; //$NON-NLS-1$ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final String pathInfo = req.getPathInfo(); String result = ""; //$NON-NLS-1$ // startswith also covers models if (pathInfo == null || pathInfo.trim().length() == 0) { result = getEPackageList(req); resp.setContentType("text/html;charset=UTF-8"); //$NON-NLS-1$ } else { // get rid of the preceding / String name = pathInfo.substring(1); if (name.contains("/")) { //$NON-NLS-1$ int segmentIndex = name.indexOf("/"); //$NON-NLS-1$ name = name.substring(0, segmentIndex); } // must be an eclass then with an instance possibly if (pathInfo.contains(ModelUtils.QUALIFIERSEPARATOR)) { if (name.contains("/")) { //$NON-NLS-1$ name = name.substring(0, name.indexOf("/")); //$NON-NLS-1$ } final EClass eClass = ModelUtils.getEClassFromQualifiedName(name); doGetInstances(eClass, req, resp); } else { // try to be robust... name = name.toLowerCase(); // an epackage for (ModelPackage modelPackage : ServiceModelPackageRegistry.getInstance().getRegisteredModelPackages()) { if (modelPackage.getEPackage().getName().toLowerCase().equals(name)) { if (req.getParameter(ACTION_PARAMETER) != null && req.getParameter(ACTION_PARAMETER).toLowerCase().equals(GENERATE_TEST_DATA_ACTION)) { // generate test data and report the results result = generatePersistTestData(modelPackage.getEPackage()); } else { result = getTypes(req, modelPackage.getEPackage()); } resp.setContentType("text/html;charset=UTF-8"); //$NON-NLS-1$ break; } } } } if (result == null) { result = "No results found using this url"; //$NON-NLS-1$ } // and return what we have... resp.getWriter().write(result); } /** * Can be overridden by example servlets to generate test data. Is not done here to prevent dependency of server * plugin on datagenerator. */ protected String generatePersistTestData(EPackage ePackage) { return "The test data generation should be implemented in a subclass of this servlet"; //$NON-NLS-1$ } /** * Return (as html) the current list of epackages registered in the {@link ServiceModelPackageRegistry}. */ protected String getEPackageList(HttpServletRequest req) { final StringBuilder sb = new StringBuilder(); sb.append("<html><body><h1>Registered Model Packages</h1>"); //$NON-NLS-1$ sb.append("<table>"); //$NON-NLS-1$ for (ModelPackage modelPackage : ServiceModelPackageRegistry.getInstance().getRegisteredModelPackages()) { sb.append("<tr><td><b>"); //$NON-NLS-1$ sb.append(modelPackage.getEPackage().getName() + " --> "); //$NON-NLS-1$ sb.append("</b></td><td>"); //$NON-NLS-1$ sb.append("<a href='" + req.getContextPath() + req.getServletPath() + "/" + modelPackage.getEPackage().getName() + "'>Browse Types</a>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ sb.append("</td><td>"); //$NON-NLS-1$ sb.append("<a href='" + req.getContextPath() + req.getServletPath() + "/" + modelPackage.getEPackage().getName() + "?" + ACTION_PARAMETER + "=" + GENERATE_TEST_DATA_ACTION + "'>Generate Test Data</a>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ sb.append("</td><tr>"); //$NON-NLS-1$ } sb.append("</table></body></html>"); //$NON-NLS-1$ return sb.toString(); } /** * Return (in html) the current list of types of an epackage. */ protected String getTypes(HttpServletRequest req, EPackage ePackage) { final StringBuilder sb = new StringBuilder(); sb.append("<html><body><h1>Types list for EPackage " + ePackage.getName() + "</h1>"); //$NON-NLS-1$ //$NON-NLS-2$ sb.append("<table>"); //$NON-NLS-1$ for (EClassifier eClassifier : ePackage.getEClassifiers()) { if (eClassifier instanceof EClass) { final EClass eClass = (EClass) eClassifier; sb.append("<tr><td>"); //$NON-NLS-1$ sb.append("<a href='" + req.getContextPath() + req.getServletPath() + "/" + ModelUtils.getQualifiedNameFromEClass(eClass) + "?" + TEMPLATE_PARAMETER + "=instances.xslt'>" + eClass.getName() + "</a> "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ sb.append("<a href='" + req.getContextPath() + req.getServletPath() + "/" + ModelUtils.getQualifiedNameFromEClass(eClass) + "'>(xml)</a>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ sb.append("</td><tr>"); //$NON-NLS-1$ } } sb.append("</table></body></html>"); //$NON-NLS-1$ return sb.toString(); } /** * Return (in html) the list of records of a type */ protected void doGetInstances(EClass eClass, HttpServletRequest req, HttpServletResponse resp) throws IOException { final String templateLocation = req.getParameter(TEMPLATE_PARAMETER); final String type = req.getParameter(TYPE_PARAMETER); final WebServiceHandler webServiceHandler = createWebServiceHandler(type == null || type.equalsIgnoreCase(TYPE_PARAMETER_XML)); if (templateLocation != null) { final XSLTServiceContextResultProcessor serviceContextResultProcessor = ComponentProvider.getInstance() .newInstance(XSLTServiceContextResultProcessor.class); serviceContextResultProcessor.setTemplateClassPathLocation(templateLocation); webServiceHandler.setServiceContextResultProcessor(serviceContextResultProcessor); serviceContextResultProcessor.addParameter("eClassName", eClass.getName()); //$NON-NLS-1$ serviceContextResultProcessor.addParameter("qualifiedEClassName", ModelUtils.getQualifiedNameFromEClass(eClass)); //$NON-NLS-1$ } webServiceHandler.doGet(req, resp); } protected WebServiceHandler createWebServiceHandler(boolean xml) { if (xml) { return ComponentProvider.getInstance().newInstance(XMLRestWebServiceHandler.class); } throw new IllegalArgumentException("Unsupported type of web service handler"); //$NON-NLS-1$ } /** * Return (in html) an instance */ protected String getInstance(EClass eClass, Object id) { return null; } public String applyTemplate(String xml, InputStream template) { try { final TransformerFactory factory = TransformerFactory.newInstance(); final Transformer transformer = factory.newTransformer(new StreamSource(template)); final StreamSource source = new StreamSource(new StringReader(xml)); final StringWriter sw = new StringWriter(); final StreamResult response = new StreamResult(sw); transformer.transform(source, response); return sw.toString(); } catch (final Exception e) { throw new IllegalStateException(e); } } }