/* * Lokomo OneCMDB - An Open Source Software for Configuration * Management of Datacenter Resources * * Copyright (C) 2006 Lokomo Systems AB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via * paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33 * Danderyd, Sweden. * */ package org.onecmdb.ui.gwt.desktop.server.transform; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.Writer; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Properties; import org.apache.log4j.Appender; import org.apache.log4j.Logger; import org.onecmdb.core.utils.bean.AttributeBean; import org.onecmdb.core.utils.bean.CiBean; import org.onecmdb.core.utils.bean.ValueBean; import org.onecmdb.core.utils.graph.query.GraphQuery; import org.onecmdb.core.utils.graph.query.constraint.RelationConstraint; import org.onecmdb.core.utils.graph.query.selector.ItemAliasSelector; import org.onecmdb.core.utils.graph.query.selector.ItemRelationSelector; import org.onecmdb.core.utils.graph.query.selector.ItemSelector; import org.onecmdb.core.utils.graph.result.Graph; import org.onecmdb.core.utils.graph.result.Template; import org.onecmdb.core.utils.wsdl.IOneCMDBWebService; import org.onecmdb.core.utils.wsdl.OneCMDBServiceFactory; import org.onecmdb.core.utils.xml.XmlGenerator; import org.onecmdb.utils.wsdl.SimpleArg; import org.onecmdb.utils.xml.Graph2XML; import org.onecmdb.utils.xml.XML2GraphQuery; /** * <code>DumpOneCMDB</code> retrieve CI and produce XML as output. * * */ public class OneCMDBTransform { protected static String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //protected static String XML_HEADER = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"; private HashMap<String, CiBean> templateMap = new HashMap<String, CiBean>(); private Throwable transformException; private Throwable writerException; private Properties attrMap; private String xmlStyle = ""; private boolean deepTree = false; private static String ARGS[][] = { {"url", "WSDL URL excluding ?WSDL", "http://localhost:8080/webservice/onecmdb"}, {"user", "The user to login as.", "admin"}, {"pwd", "The user to login as.", "123"}, {"token", "A login token", null}, {"queryURL", "A url containing a cmdb query", null}, {"xslt", "Transform output...", null}, {"output", "Output file, - stdout", "-"}, {"transform", "Perfom the transformation", "true"}, {"style", "Structure of xml data generated before xslt[onecmdb, tree, deeptree, graph]", "onecmdb"} }; public static void main(String argv[]) { SimpleArg arg = new SimpleArg(ARGS); String url = arg.getArg(ARGS[0][0], argv); String username = arg.getArg(ARGS[1][0], argv); String pwd = arg.getArg(ARGS[2][0], argv); String token = arg.getArg(ARGS[3][0], argv); String queryFile = arg.getArg(ARGS[4][0], argv); String xslt = arg.getArg(ARGS[5][0], argv); String output = arg.getArg(ARGS[6][0], argv); String transform = arg.getArg(ARGS[7][0], argv); String style = arg.getArg(ARGS[8][0], argv); if (transform.equals("false")) { xslt = null; } if (queryFile == null) { System.out.println("--queryURL is missing!"); arg.showHelp(); } // Disable Console logger. Appender consoleAppender = Logger.getRootLogger().getAppender("stdout"); Logger.getRootLogger().removeAppender(consoleAppender); OneCMDBTransform query = new OneCMDBTransform(); query.setServiceURL(url); query.setUsername(username); query.setPwd(pwd); query.setToken(token); query.setQueryFile(queryFile); query.setOutput(output); query.setXSLT(xslt); query.setXmlStyle(style); try { query.process(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void process() throws Throwable { PrintWriter rStream = new PrintWriter(System.out); if (!getOutput().equals("-")) { rStream = new PrintWriter(new OutputStreamWriter(new FileOutputStream(getOutput()), "UTF-8")); } process(rStream); } public void process(final PrintWriter resultStream) throws Throwable { GraphQuery selQuery = null; XML2GraphQuery parser = new XML2GraphQuery(); parser.setAttributeMap(attrMap); if (this.query != null) { StringReader reader = new StringReader(this.query); selQuery = parser.parse(reader); } else if (queryFile.equals("-")) { selQuery = parser.parse(System.in, "UTF-8"); } else { parser.setQueryURL(queryFile); selQuery = parser.parse(); } final GraphQuery query = selQuery; final ItemSelector primary = query.fetchPrimarySelectors(); if (primary == null) { throw new IllegalArgumentException("No primary selector found!"); } final Graph result = getService().queryGraph(getToken(), query); result.buildMap(); PipedOutputStream pOut = new PipedOutputStream(); PipedInputStream in = new PipedInputStream(pOut); final Reader input = new InputStreamReader(in, "UTF-8"); //final Reader input = new InputStreamReader(in); OutputStreamWriter out = new OutputStreamWriter(pOut, "UTF-8"); //final OutputStreamWriter out = new OutputStreamWriter(pOut); final PrintWriter pw = new PrintWriter(out, true); // Start consumer... Thread thread = new Thread(new Runnable() { public void run() { try { if (getXSLT() != null) { URL url = null; if (getXSLT().startsWith("classpath:")) { String name = getXSLT().substring("classpath:".length()); url = getClass().getClassLoader().getResource(name); } else { url = new URL(getXSLT()); } InputStream xsltStream = url.openStream(); InputStreamReader reader = new InputStreamReader(xsltStream); transform(input, reader, resultStream); resultStream.flush(); } else if (getXsltData() != null) { StringReader reader = new StringReader(getXsltData()); transform(input, reader, resultStream); resultStream.flush(); } else { // Transfer to System.out; boolean eof = false; int bufSize = 1024; char[] buf = new char[bufSize]; while(!eof) { //System.out.println("START READ"); int len = input.read(buf, 0, bufSize); //System.out.println("READ[" + len + "]"); if (len < 0) { eof = true; continue; } resultStream.write(buf, 0, len); } resultStream.flush(); System.out.println("EOF..."); } } catch (Exception e) { e.printStackTrace(); transformException = e; } finally { } System.out.println("READER THREAD DIEs"); } }); thread.start(); Thread writer = new Thread(new Runnable() { public void run() { try { System.out.println("Writer starts"); try { if (xmlStyle == null) { xmlStyle = ""; } if (xmlStyle.equals("onecmdb")) { List<CiBean> beans = new ArrayList<CiBean>(); beans.addAll(result.fetchAllNodeOffsprings()); XmlGenerator gen = new XmlGenerator(); gen.setBeans(beans); gen.transfer(pw); } else if (xmlStyle.equals("tree") || xmlStyle.equals("deeptree")) { // Produce tree... if (xmlStyle.equals("deeptree")) { deepTree = true; } pw.println(XML_HEADER); pw.println("<Tree>"); for (ItemSelector sel : query.fetchSelectors()) { if (sel.isPrimary()) { Template t = result.fetchNode(sel.getId()); printTemplateTree(pw, t, query, result, "/" + t.getId(), 1); } } pw.println("</Tree>"); } else if (xmlStyle.length() == 0 || xmlStyle.equals("graph")){ // Default... pw.println(XML_HEADER); pw.println(new Graph2XML().toXML(result, 0)); /* pw.println("<Graph>"); printGraph(pw, result, 1); pw.println("</Graph>"); */ } //else if (xmlStyle.length() == 0 || xmlStyle.equals(anObject)) } finally { try { pw.flush(); pw.close(); } catch (Throwable t) { } } } catch (Throwable t) { writerException = t; } System.out.println("WRITER THREAD DIEs"); } }); writer.start(); //Thread.sleep(1000); System.out.println("Wait for reader"); synchronized(thread) { thread.join(); } System.out.println("Wait for writer"); // Kill Writer. synchronized (writer) { writer.interrupt(); } // Check if Transform has raised any exception. if (transformException != null) { throw transformException; } System.out.println("End of thread.."); } private void printGraph(PrintWriter pw, Graph result, int tab) { pw.println(getTab(tab) + "<Nodes>"); for(Template t : result.getNodes()) { pw.println(getTab(tab+1) + "<Node id=\"" + t.getId() + "\" type=\"" + t.getTemplate().getAlias() + "\">"); if (t.getOffsprings() != null) { for (CiBean bean : t.getOffsprings()) { pw.println(bean.toXML(tab+2)); } } pw.println(getTab(tab+1) + "</Node>"); } pw.println(getTab(tab) + "</Nodes>"); pw.println(getTab(tab) + "<Edges>"); for(Template t : result.getEdges()) { pw.println(getTab(tab+1) + "<Edge id=\"" + t.getId() + "\">"); if (t.getTemplate() != null) { pw.println(getTab(tab+2) + "<Template>"); pw.println(t.getTemplate().toXML(tab+3)); pw.println(getTab(tab+2) + "</Template>"); } if (t.getOffsprings() != null) { for (CiBean bean : t.getOffsprings()) { pw.println(bean.toXML(tab+2)); } } pw.println(getTab(tab+1) + "</Edge>"); } pw.print(getTab(tab) + "</Edges>"); } public void transform(Reader xmlInputStream, Reader xslt, Writer resultStream) throws javax.xml.transform.TransformerException { javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource(xmlInputStream); javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(xslt); javax.xml.transform.Result result = new javax.xml.transform.stream.StreamResult(resultStream); // create an instance of TransformerFactory javax.xml.transform.TransformerFactory transFact = javax.xml.transform.TransformerFactory.newInstance( ); javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource); trans.transform(xmlSource, result); } public static String toXmlString(String s) { if (s == null) { return(""); } s = s.trim(); StringBuffer sb = new StringBuffer(); int len = s.length(); for (int i = 0; i < len; i++) { char c = s.charAt(i); switch (c) { default: sb.append(c); break; case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '&': sb.append("&"); break; case '"': sb.append("""); break; case '\'': sb.append("'"); break; } } return(sb.toString()); } private void printTemplateTree(PrintWriter pw, Template t, GraphQuery query, Graph result, String path, int level) throws Exception { for (CiBean bean : t.getOffsprings()) { if (bean.isTemplate()) { pw.println(getTab(level) + "<" + t.getId() + ">"); pw.print(bean.toXML(level+1)); pw.println(getTab(level) + "</" + t.getId() + ">"); continue; } CiBean tBean = getTemplateFor(bean); pw.println(getTab(level) + "<" + t.getId() + " alias=\"" + bean.getAlias() + "\" id=\"" + bean.getIdAsString() + "\"" + " type=\"" + bean.getDerivedFrom() + "\" " + " createDate=\"" + CiBean.toXmlDateTime(bean.getCreateDate()) + "\" " + " modifyDate=\"" + CiBean.toXmlDateTime(bean.getLastModified()) + "\"" + ">"); for (AttributeBean aBean : tBean.getAttributes()) { if (aBean.isComplexType()) { continue; } List<ValueBean> vBeans = bean.fetchAttributeValueBeans(aBean.getAlias()); if (vBeans.size() == 0) { pw.println(getTab(level+1) + "<" + aBean.getAlias() + "></" + aBean.getAlias() + ">"); } else { for (ValueBean vBean : vBeans) { pw.println(getTab(level+1) + "<" + aBean.getAlias() + ">" + toXmlString(vBean.getValue()) + "</" + aBean.getAlias() + ">"); } } } // Handle references. for (ItemRelationSelector rel : query.getItemRelationSelector()) { if (!deepTree) { if (path.contains("/" + rel.getId())) { continue; } } if (rel.getSource().equals(t.getId())) { Template referenced = result.fetchReference(bean, RelationConstraint.SOURCE, rel.getId()); referenced.setId(rel.getTarget()); Template refT = result.fetchNode(rel.getTarget()); referenced.setTemplate(refT.getTemplate()); pw.println(getTab(level+1) + "<" + rel.getId() + " direction=\"OUTBOUND\">"); String newPath = path; if (deepTree) { if (path.contains("/" + bean.getAlias())) { continue; } newPath = path + "/" + bean.getAlias(); } else { newPath = path + "/" + rel.getId(); } printTemplateTree(pw, referenced, query, result, newPath, level+2); pw.println(getTab(level+1) + "</" + rel.getId() + ">"); } if (rel.getTarget().equals(t.getId())) { Template referenced = result.fetchReference(bean, RelationConstraint.TARGET, rel.getId()); referenced.setId(rel.getSource()); Template refT = result.fetchNode(rel.getSource()); referenced.setTemplate(refT.getTemplate()); pw.println(getTab(level+1) + "<" + rel.getId() + " direction=\"INBOUND\">"); String newPath = path; if (deepTree) { if (path.contains("/" + bean.getAlias())) { continue; } newPath = path + "/" + bean.getAlias(); } else { newPath = path + "/" + rel.getId(); } printTemplateTree(pw, referenced, query, result, newPath, level+2); pw.println(getTab(level+1) + "</" + rel.getId() + ">"); } } pw.println(getTab(level) + "</" + t.getId() + ">"); } } private CiBean getTemplateFor(CiBean bean) throws Exception { CiBean t = templateMap.get(bean.getDerivedFrom()); if (t != null) { return(t); } // Query for template... ItemAliasSelector off = new ItemAliasSelector(bean.getDerivedFrom(), bean.getDerivedFrom()); off.setAlias(bean.getDerivedFrom()); off.setPrimary(true); GraphQuery q = new GraphQuery(); q.addSelector(off); Graph result = getService().queryGraph(getToken(), q); Template tRes = result.fetchNode(off.getId()); if (tRes.getOffsprings().size() == 0) { throw new IllegalArgumentException("Template <" + bean.getDerivedFrom() + "> is missing!"); } CiBean template = tRes.getOffsprings().get(0); templateMap.put(template.getAlias(), template); return(template); } private String getTab(int n) { String tab = ""; for (int i = 0; i < n; i++) { tab += "\t"; } return(tab); } private String username; private String pwd; private String queryFile; private String serviceURL; private IOneCMDBWebService service; private String token; private String output; private String xslt; private String query; private String xsltData; public String getQuery() { return query; } public void setQuery(String query) { this.query = query; } public String getXsltData() { return xsltData; } public void setXsltData(String xsltData) { this.xsltData = xsltData; } public Properties getAttrMap() { return attrMap; } public void setAttrMap(Properties attrMap) { this.attrMap = attrMap; } public String getXSLT() { return xslt; } public void setXSLT(String xslt) { this.xslt = xslt; } public String getQueryFile() { return queryFile; } public void setQueryFile(String queryFile) { this.queryFile = queryFile; } public String getOutput() { return output; } public void setOutput(String output) { this.output = output; } private void logout() { if (service == null) { return; } if (token == null) { return; } service.logout(token); } public String getServiceURL() { return serviceURL; } public void setServiceURL(String service) { this.serviceURL = service; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } private IOneCMDBWebService getService() throws Exception { if (this.service == null) { this.service = OneCMDBServiceFactory.getWebService(serviceURL); if (this.token == null) { this.token = this.service.auth(getUsername(), getPwd()); } } return(service); } public void setService(IOneCMDBWebService service) { this.service = service; } public String getXmlStyle() { return xmlStyle; } public void setXmlStyle(String xmlStyle) { this.xmlStyle = xmlStyle; } }