/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.brooklyn.core.plan; import java.io.StringReader; import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType; import org.apache.brooklyn.api.entity.Application; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.core.mgmt.EntityManagementUtils; import org.apache.brooklyn.entity.stock.BasicApplication; import org.apache.brooklyn.entity.stock.BasicEntity; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.stream.ReaderInputStream; import org.w3c.dom.Document; import org.w3c.dom.Node; /** Example implementation of {@link PlanToSpecTransformer} showing * how implementations are meant to be written. */ public class XmlPlanToSpecTransformer implements PlanToSpecTransformer { // this is REPLACED by ExampleXmlTypePlanTransformer // TODO remove when PlanToSpecTransformer is removed @SuppressWarnings("unused") private ManagementContext mgmt; @Override public void setManagementContext(ManagementContext managementContext) { mgmt = managementContext; } @Override public String getShortDescription() { return "Dummy app structure created from the XML tree"; } @Override public boolean accepts(String mime) { if ("test-xml".equals(mime)) return true; return false; } @SuppressWarnings("unchecked") @Override public EntitySpec<? extends Application> createApplicationSpec(String plan) { Document dom = parseXml(plan); EntitySpec<?> result = toEntitySpec(dom, 0); if (Application.class.isAssignableFrom(result.getType())) { return (EntitySpec<Application>) result; } else { return EntityManagementUtils.newWrapperApp().child(result); } } @SuppressWarnings({ "unchecked" }) @Override public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) { if (item.getPlanYaml()==null) throw new PlanNotRecognizedException("Plan is null"); if (item.getCatalogItemType()==CatalogItemType.ENTITY) { return (SpecT)toEntitySpec(parseXml(item.getPlanYaml()), 1); } if (item.getCatalogItemType()==CatalogItemType.TEMPLATE) { return (SpecT)toEntitySpec(parseXml(item.getPlanYaml()), 0); } throw new PlanNotRecognizedException("Type "+item.getCatalogItemType()+" not supported"); } private Document parseXml(String plan) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); Document dom; try { //Using factory get an instance of document builder DocumentBuilder db = dbf.newDocumentBuilder(); //parse using builder to get DOM representation of the XML file dom = db.parse(new ReaderInputStream(new StringReader(plan))); } catch (Exception e) { Exceptions.propagateIfFatal(e); throw new PlanNotRecognizedException(e); } return dom; } private EntitySpec<?> toEntitySpec(Node dom, int depth) { if (dom.getNodeType()==Node.DOCUMENT_NODE) { if (dom.getChildNodes().getLength()!=1) { // NB: <?...?> entity preamble might break this throw new IllegalStateException("Document for "+dom+" has "+dom.getChildNodes().getLength()+" nodes; 1 expected."); } return toEntitySpec(dom.getChildNodes().item(0), depth); } EntitySpec<?> result = depth == 0 ? EntitySpec.create(BasicApplication.class) : EntitySpec.create(BasicEntity.class); result.displayName(dom.getNodeName()); if (dom.getAttributes()!=null) { for (int i=0; i<dom.getAttributes().getLength(); i++) result.configure(dom.getAttributes().item(i).getNodeName(), dom.getAttributes().item(i).getTextContent()); } if (dom.getChildNodes()!=null) { for (int i=0; i<dom.getChildNodes().getLength(); i++) { Node item = dom.getChildNodes().item(i); if (item.getNodeType()==Node.ELEMENT_NODE) { result.child(toEntitySpec(item, depth+1)); } } } return result; } }