| package org.eclipse.stem.util.loggers.htmlgeneration; |
| |
| |
| /******************************************************************************* |
| * Copyright (c) 2011 IBM Corporation. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.net.URL; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.stem.core.common.DublinCore; |
| import org.eclipse.stem.core.common.Identifiable; |
| import org.eclipse.stem.core.graph.Graph; |
| import org.eclipse.stem.core.model.Decorator; |
| import org.eclipse.stem.core.model.EdgeDecorator; |
| import org.eclipse.stem.core.model.GraphDecorator; |
| import org.eclipse.stem.core.model.Model; |
| import org.eclipse.stem.core.model.NodeDecorator; |
| import org.eclipse.stem.core.scenario.Scenario; |
| import org.eclipse.stem.core.sequencer.Sequencer; |
| import org.eclipse.stem.core.solver.Solver; |
| import org.eclipse.stem.util.loggers.Activator; |
| |
| /** |
| * |
| * @author jhkauf |
| * |
| */ |
| public class HtmlScenarioPage extends HTMLdocument { |
| |
| // readable labels |
| private static final String DECORATOR_STRING = "Decorator"; |
| private static final String DUBLIN_CORE_STRING = "Dublin Core"; |
| private static final String MODEL_STRING = "Model"; |
| private static final String MODEL_GRAPH_STRING = "Graph"; |
| |
| private static final String SCENARIO_STRING = "Scenario"; |
| private static final String SEQUENCER_STRING = "Sequencer"; |
| private static final String SOLVER_STRING = "Solver"; |
| private static final String STEM_SCENARIO_STRING = "STEM Scenario"; |
| |
| // ID's |
| private static final String DATA_ROW_ID_PREFIX = "DATA_ROW_"; |
| private static final String DUBLINCORE_ROW_ID_PREFIX = "DUBLINCORE_ROW_"; |
| private static final String TITLE_ROW_ID_PREFIX = "TITLE_ROW_"; |
| |
| // colors |
| private static final String COLOR_WHITE = "rgb(255, 255, 255)"; |
| private static final String COLOR_TITLE0 = "rgb(200, 200, 255)"; |
| private static final String COLOR_TITLE1 = "rgb(102, 255, 255)"; |
| private static final String COLOR_DATA = "rgb(202, 255, 255)"; |
| private static final String COLOR_DUBLINCORE = "rgb(200, 255, 200)"; |
| private static final String COLOR_DUBLINCORE_DATA = "rgb(225, 255, 225)"; |
| |
| // other |
| private static final String FILENAME = "ScenarioLog.html"; |
| private int indent = 0; |
| private static final String COLLAPSE = "-"; |
| private static final String EXPAND = "+"; |
| private static final String[] CELL_WIDTH = {"100px","100px","200px"}; |
| private static final String INDENT_WIDTH = "80px"; |
| |
| /** |
| * |
| * @param scenario |
| * @param directoryName |
| */ |
| public HtmlScenarioPage(Scenario scenario, String directoryName) { |
| super(); |
| |
| createDocument(scenario); |
| String fileName = directoryName + FILENAME; |
| this.writeDocument(fileName,this.getContents()); |
| } |
| |
| /** |
| * |
| * @param scenario |
| */ |
| private void createDocument(Scenario scenario) { |
| Head head = new Head(); |
| this.add(head); |
| |
| |
| String jsContent = readJsFromFile(); |
| String cssContent = readCssFromFile(); |
| |
| if (!"".equals(jsContent)) { |
| Script jsContainer = new Script("type", "text/javascript"); |
| jsContainer.setData(jsContent); |
| head.add(jsContainer); |
| } |
| |
| if (!"".equals(cssContent)) { |
| Style cssContainer = new Style("type", "text/css"); |
| cssContainer.setData(cssContent); |
| head.add(cssContainer); |
| } |
| |
| Model parentModel = scenario.getModel(); |
| EList<Decorator> decoratorList = scenario.getScenarioDecorators(); |
| Sequencer sequencer = scenario.getSequencer(); |
| Solver solver = scenario.getSolver(); |
| |
| // set up the title |
| String scenarioURI = scenario.getURI().toString(); |
| String scenarioTitle = getShortName(scenarioURI); |
| Title title = new Title(scenarioTitle); |
| head.add(title); |
| |
| Body body = new Body(); |
| body.addAttribute("onload", "collapseDublinCores();"); |
| this.add(body); |
| |
| |
| Table table = new Table("style","text-align: left; width: 100%;"); |
| table.addAttribute("border", "4"); |
| table.addAttribute("cellpadding", "2"); |
| table.addAttribute("cellspacing", "5"); |
| body.add(table); |
| |
| Tbody tbody = new Tbody(); |
| table.add(tbody); |
| table.setTbody(tbody); |
| |
| TR tr = new TR("id",TITLE_ROW_ID_PREFIX+scenarioTitle); |
| tr.addAttribute("align","left"); |
| tbody.add(tr); |
| TD td = new TD("style","background-color: "+COLOR_TITLE0+";"); |
| tr.add(td); |
| Span span2 = new Span("style","font-weight: bold;"); |
| span2.setData(COLLAPSE+STEM_SCENARIO_STRING+": "+scenarioTitle); |
| td.add(span2); |
| |
| |
| |
| // Add the scenario itself. the method adds it to the parent as well. |
| Table scenarioTable = getNewTable(tbody); |
| populateTablefromObject(scenarioTable.getTbody(), scenario, SCENARIO_STRING, null, true); |
| // Add all the Scenario's decorators |
| addSectionList(scenarioTable.getTbody(), decoratorList, DECORATOR_STRING, true); |
| // Iterate through the Scenario's sequencer |
| populateTablefromObject(scenarioTable.getTbody(), sequencer, SEQUENCER_STRING, null, true); |
| // Iterate through the Scenario's SOLVER |
| populateTablefromObject(scenarioTable.getTbody(), solver, SOLVER_STRING, null, true); |
| |
| |
| // DESCEND into the Scenario's parent Model |
| addModelContents(tbody, parentModel, true); |
| |
| |
| |
| |
| /* |
| TR tr2 = new TR(); |
| tbody.add(tr2); |
| TD td2 = new TD(); |
| tr2.add(td2); |
| UL ul = new UL(); |
| td2.add(ul); |
| |
| LI li1 = new LI("modelA"); |
| LI li2 = new LI("modelB"); |
| ul.add(li1); |
| UL ul2 = new UL(); |
| ul.add(ul2); |
| ul2.add(li2); |
| UL ul3 = new UL(); |
| ul2.add(ul3); |
| LI li2a = new LI("decorator1"); |
| LI li2b = new LI("decorator2"); |
| ul3.add(li2a); |
| ul3.add(li2b); |
| LI li3 = new LI("sequencer"); |
| LI li4 = new LI("solver"); |
| ul.add(li3); |
| ul.add(li4); |
| */ |
| |
| this.writeDocument("/test.html",this.getContents()); |
| //System.out.println(doc.getContents()); |
| }// createDocument() |
| |
| |
| /** |
| * |
| * @param tbody |
| * @param model |
| * @param top |
| */ |
| public void addModelContents(final Tbody tbody, final Model model, boolean top) { |
| // DESCEND into the Scenario's parent Model |
| if(model!=null) { |
| indent++; |
| // create the model table and add to the parent itself |
| final Table modelTable = getNewTable(tbody); |
| |
| populateTablefromObject(modelTable.getTbody(), model, MODEL_STRING, null, true ); |
| final Tbody modelTableBody = modelTable.getTbody(); |
| |
| |
| |
| // The models decorators |
| final EList<NodeDecorator> nodeDecoratorList = model.getNodeDecorators(); |
| if((nodeDecoratorList!=null)&&(nodeDecoratorList.size()>=1)) { |
| addSectionList(modelTableBody, nodeDecoratorList, DECORATOR_STRING, true); |
| } |
| |
| final EList<EdgeDecorator> edgeDecoratorList = model.getEdgeDecorators(); |
| if((edgeDecoratorList!=null)&&(edgeDecoratorList.size()>=1)) { |
| addSectionList(modelTableBody, edgeDecoratorList, DECORATOR_STRING, true); |
| } |
| |
| final EList<GraphDecorator> graphDecoratorList = model.getGraphDecorators(); |
| if((graphDecoratorList!=null)&&(graphDecoratorList.size()>=1)) { |
| addSectionList(modelTableBody, graphDecoratorList, DECORATOR_STRING, true); |
| } |
| EList<Graph> graphList = model.getGraphs(); |
| if((graphList!=null)&&(graphList.size()>=1)) { |
| addSectionList(modelTableBody, graphList, MODEL_GRAPH_STRING, true); |
| } |
| |
| // Recurse into the model |
| final EList<Model> modelList = model.getModels(); |
| if((modelList!=null)&&(modelList.size()>=1)&&(modelTableBody!=null)) { |
| for(int i = 0; i < modelList.size(); i++) { |
| Model innerModel = modelList.get(i); |
| addModelContents(tbody, innerModel, false ); |
| }// for all models inside |
| } |
| |
| }// model not null |
| }//addModelContents |
| |
| /** |
| * |
| * @param tbody |
| * @param eList |
| * @param type |
| * @param addDublinCore |
| */ |
| public void addSectionList(Tbody tbody, EList<?> eList, String type, boolean addDublinCore) { |
| if(eList!=null) { |
| for(int i = 0; i < eList.size(); i ++) { |
| Object object = eList.get(i); |
| // should always be true |
| if(object instanceof EObject) { |
| populateTablefromObject(tbody, (EObject) object, type, null, addDublinCore); |
| } |
| |
| }// for all identifiable |
| } |
| }// addSectionList |
| |
| |
| |
| |
| |
| /** |
| * |
| * @param table |
| * @param eObject |
| * @param description |
| * @param name |
| * @param addDublinCore |
| */ |
| private void populateTablefromObject(Tbody tbody, EObject eObject, String description, String name, boolean addDublinCore) { |
| |
| if(eObject != null) { |
| |
| |
| // check the name |
| if((eObject instanceof Identifiable)) { |
| // IF the name is not forced, look it up |
| if((name==null)||(name.length()==0)){ |
| Identifiable ident = (Identifiable) eObject; |
| name = getShortName(ident.getURI().toString()); |
| } |
| } |
| |
| String eClass = eObject.eClass().getName(); |
| |
| TR trSpacer = new TR(); |
| |
| tbody.add(trSpacer); |
| indentTableRow(trSpacer); |
| |
| String rowId = TITLE_ROW_ID_PREFIX+name; |
| |
| TR tr = new TR("id",rowId); |
| tr.addAttribute("class", "idHeader"); |
| indentTableRow(tr); |
| tbody.add(tr); |
| |
| //the three HEADER columns |
| for(int i = 0; i < 3; i ++) { |
| TD td = new TD(); |
| //td.addAttribute("style", "width: "+CELL_WIDTH[i]+";"); |
| tr.add(td); |
| |
| //td.addAttribute("style","background-color: "+COLOR_TITLE1+";"); |
| if(i==0) { |
| |
| A anchor = new A(null,null); |
| anchor.addAttribute("href", "#"); |
| anchor.addAttribute("onclick", "toggle(this);return false;"); |
| anchor.addAttribute("id", rowId+"_toggle"); |
| anchor.setData(COLLAPSE+description); |
| td.add(anchor); |
| //Span span = new Span("style","font-weight: bold;"); |
| //span.setData(COLLAPSE+description); |
| //td.add(span); |
| } |
| |
| if((name == null) ||(name.length()==0)){ |
| name = "name not set"; |
| } |
| |
| if(i==1){ |
| // Span span = new Span("style","font-weight: bold;"); |
| // span.setData(name); |
| // td.add(span); |
| td.setData(name); |
| } |
| |
| if(i==2){ |
| // Span span = new Span("style","font-weight: bold;"); |
| // span.setData(eClass); |
| // td.add(span); |
| td.setData(eClass); |
| } |
| |
| } |
| |
| |
| EList<EAttribute> attrList = eObject.eClass().getEAllAttributes(); |
| |
| if(attrList!=null){ |
| |
| for(int i = 0; i < attrList.size(); i ++) { |
| EAttribute feature = attrList.get(i); |
| if(!feature.isTransient()) { |
| |
| String attribute = feature.getName(); |
| Object target = eObject.eGet(feature); |
| if(target !=null) { |
| String val = target.toString(); |
| |
| if(val.length()>=1) { |
| |
| // label every data row with a unique ID |
| String idSuffix = null; |
| if(eObject instanceof Identifiable) { |
| Identifiable ident = (Identifiable) eObject; |
| idSuffix = ident.getURI().toString(); |
| } else { |
| double r = Math.random(); |
| r *= 1e8; |
| idSuffix = "id"+((int)r); |
| } |
| idSuffix += "_"+attribute; |
| |
| TR tr2 = new TR("id",DATA_ROW_ID_PREFIX+i+"_"+idSuffix); |
| |
| tr2.addAttribute("class", "idBody"); |
| |
| //tr2.addAttribute("align","left"); |
| indentTableRow(tr2); |
| tbody.add(tr2); |
| |
| TD td1 = new TD("align","left"); |
| tr2.add(td1); |
| |
| |
| // td1.addAttribute("style", "width: "+CELL_WIDTH[0]+";"); |
| // td1.addAttribute("style","background-color: "+COLOR_DATA+";"); |
| |
| |
| |
| TD td2 = new TD("align","right"); |
| tr2.add(td2); |
| td2.setData(attribute+": "); |
| |
| // td2.addAttribute("style", "width: "+CELL_WIDTH[1]+";"); |
| // td2.addAttribute("style","background-color: "+COLOR_DATA+";"); |
| // Span span2 = new Span("style","font-weight: normal;"); |
| // span2.setData(attribute+": "); |
| // td2.add(span2); |
| |
| |
| |
| TD td3 = new TD("align","left"); |
| tr2.add(td3); |
| td3.setData(val); |
| |
| //td3.addAttribute("style", "width: "+CELL_WIDTH[2]+";"); |
| //td3.addAttribute("style","background-color: "+COLOR_DATA+";"); |
| // Span span3 = new Span("style","font-weight: normal;"); |
| // span3.setData(val); |
| // td3.add(span3); |
| |
| |
| |
| |
| |
| |
| }// string length >0 |
| } // target attribute not null |
| }// not transient? |
| |
| }// for all attributes |
| }// attrList |
| |
| |
| if(addDublinCore) { |
| Identifiable ident= (Identifiable)eObject; |
| |
| DublinCore dc = ident.getDublinCore(); |
| if(ident != null) { |
| addDCtoTable(dc, tbody); |
| } |
| } |
| |
| |
| }// object not null |
| |
| } // populateTableFromObject |
| |
| |
| |
| /** |
| * |
| * @param dublinCore |
| * @param tbody |
| */ |
| private void addDCtoTable(DublinCore dublinCore, Tbody tbody) { |
| |
| TR tr = new TR("align","center"); |
| tbody.add(tr); |
| |
| |
| EList<EStructuralFeature> attrList = dublinCore.eClass().getEStructuralFeatures(); |
| if(attrList!=null){ |
| |
| for(int i = 0; i < attrList.size(); i ++) { |
| EAttribute attr = (EAttribute)attrList.get(i); |
| Object obj = dublinCore.eGet(attr); |
| if(obj != null) { |
| String val = obj.toString(); |
| if(val.length()>=0) { |
| |
| // label every dublin core row with a unique ID |
| String idSuffix = dublinCore.getIdentifier(); |
| if((idSuffix==null)||(idSuffix.length()==0)) { |
| double r = Math.random(); |
| r *= 1e8; |
| idSuffix = "id"+((int)r); |
| } |
| |
| String rowId = DUBLINCORE_ROW_ID_PREFIX+i+"_"+idSuffix; |
| |
| TR tr2 = new TR("id",rowId); |
| //tr2.addAttribute("align","left"); |
| tbody.add(tr2); |
| |
| // indentation |
| indentTableRow(tr2); |
| |
| |
| // col 1 |
| TD td1 = new TD(); |
| td1.addAttribute("style", "width: "+CELL_WIDTH[0]+";"); |
| td1.addAttribute("class", "dcHeader"); |
| |
| //td1.addAttribute("style","background-color: "+COLOR_DUBLINCORE+";"); |
| if(i==0) { |
| |
| A anchor = new A("href", "#"); |
| anchor.addAttribute("onclick", "toggle(this);return false;"); |
| anchor.setData(EXPAND+DUBLIN_CORE_STRING); |
| td1.add(anchor); |
| |
| // Span span1 = new Span("style","font-weight: normal;"); |
| // span1.setData(COLLAPSE+DUBLIN_CORE_STRING); |
| // td1.add(span1); |
| } |
| tr2.add(td1); |
| |
| |
| // col 2 |
| TD td2 = new TD("align","right"); |
| td2.addAttribute("style", "width: "+CELL_WIDTH[1]+";"); |
| //td2.addAttribute("style","background-color: "+COLOR_DUBLINCORE_DATA+";"); |
| td2.addAttribute("class", "dcBody"); |
| td2.setData(attr.getName()+": "); |
| tr2.add(td2); |
| |
| // Span span2 = new Span("style","font-weight: normal;"); |
| // span2.setData(attr.getName()+": "); |
| // td2.add(span2); |
| // tr2.add(td2); |
| |
| |
| // col 3 |
| TD td3 = new TD(); |
| td3.addAttribute("style", "width: "+CELL_WIDTH[2]+";"); |
| td3.addAttribute("class", "dcBody"); |
| //td3.addAttribute("style","background-color: "+COLOR_DUBLINCORE_DATA+";"); |
| td3.setData(val); |
| tr2.add(td3); |
| |
| |
| // Span span3 = new Span("style","font-weight: normal;"); |
| // span3.setData(val); |
| // td3.add(span3); |
| |
| } |
| } |
| |
| } |
| } |
| |
| }//addDCtoTable() |
| |
| |
| /** |
| * make a new inner table |
| * @param parentTableBody |
| * @return a new table |
| */ |
| public Table getNewTable(Tbody parentTableBody) { |
| Table newTable = new Table("style","text-align: left;"); |
| newTable.addAttribute("width", "100%"); |
| newTable.addAttribute("border", "0"); |
| newTable.addAttribute("frame", "box"); |
| newTable.addAttribute("cellpadding", "2"); |
| newTable.addAttribute("cellspacing", "2"); |
| Tbody newTbody = new Tbody(); |
| newTable.add(newTbody); |
| newTable.setTbody(newTbody); |
| |
| |
| TR trParent = new TR(); |
| parentTableBody.add(trParent); |
| TD tdParent = new TD(); |
| trParent.add(tdParent); |
| tdParent.add(newTable); |
| |
| |
| // Spacer row |
| TR trSpacer = new TR(); |
| newTbody.add(trSpacer); |
| // indent spacer cols |
| indentTableRow(trSpacer); |
| // and three cols of data |
| for(int i = 0; i < 3; i ++) { |
| // the header line in its' own color |
| TD td = new TD("style","background-color: "+COLOR_WHITE+";"); |
| td.addAttribute("style", "width: "+CELL_WIDTH[i]+";"); |
| trSpacer.add(td); |
| } |
| // fill any remaining space to the right |
| TD td2 = new TD("style","background-color: "+COLOR_WHITE+";"); |
| trSpacer.add(td2); |
| |
| return newTable; |
| }//getNewTable() |
| |
| |
| /** |
| * |
| * @param trSpacer |
| */ |
| public void indentTableRow(TR trSpacer) { |
| // indent spacer cols |
| for(int i = 0; i < indent; i ++) { |
| // the header line in its' own color |
| TD td = new TD(); |
| td.addAttribute("style", "width: "+INDENT_WIDTH+";"); |
| td.addAttribute("class", "blank"); |
| trSpacer.add(td); |
| } |
| }// indent table row |
| |
| /** |
| * |
| * @param longName |
| * @return the short name |
| */ |
| public static String getShortName(String longName) { |
| int idx = longName.lastIndexOf("/"); |
| String name = longName.substring(idx+1, longName.length()); |
| idx = name.indexOf("."); |
| if(idx >=3) { |
| name = name.substring(0,idx); |
| } |
| if((name==null)||(name.length()==0)) { |
| name = "Name not set"; |
| } |
| return name; |
| } |
| |
| |
| private String readJsFromFile() |
| { |
| return readFromFile("resources/source.js"); |
| } |
| |
| private String readCssFromFile() |
| { |
| return readFromFile("resources/source.css"); |
| } |
| |
| private String readFromFile(String fileName) |
| { |
| StringBuilder data = new StringBuilder(); |
| URL jsData = Activator.getDefault().getBundle().getResource(fileName); |
| if (jsData != null) { |
| BufferedReader reader = null; |
| try { |
| reader = new BufferedReader(new InputStreamReader(jsData.openStream())); |
| char[] buf = new char[1024]; |
| int bytesRead=0; |
| while((bytesRead=reader.read(buf)) != -1){ |
| data.append(buf, 0, bytesRead); |
| } |
| } catch (IOException ioe) { |
| // don't care |
| ioe.printStackTrace(); |
| } finally { |
| try { |
| reader.close(); |
| } catch (Exception e) { |
| // do nothing |
| } |
| } |
| } |
| |
| return data.toString(); |
| } |
| |
| |
| } |