Search in sources :

Example 1 with XmlReader

use of tuwien.auto.calimero.xml.XmlReader in project openremote by openremote.

the class KNXProtocol method discoverLinkedAssetAttributes.

@Override
public Asset[] discoverLinkedAssetAttributes(AssetAttribute protocolConfiguration, FileInfo fileInfo) throws IllegalStateException {
    ZipInputStream zin = null;
    try {
        boolean fileFound = false;
        byte[] data = CodecUtil.decodeBase64(fileInfo.getContents());
        zin = new ZipInputStream(new ByteArrayInputStream(data));
        ZipEntry zipEntry = zin.getNextEntry();
        while (zipEntry != null) {
            if (zipEntry.getName().endsWith("/0.xml")) {
                fileFound = true;
                break;
            }
            zipEntry = zin.getNextEntry();
        }
        if (!fileFound) {
            String msg = "Failed to find '0.xml' in project file";
            LOG.info(msg);
            throw new IllegalStateException(msg);
        }
        // Create a transform factory instance.
        System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
        TransformerFactory tfactory = TransformerFactory.newInstance();
        // Create a transformer for the stylesheet.
        Transformer transformer = tfactory.newTransformer(new StreamSource(this.getClass().getResourceAsStream("/org/openremote/agent/protocol/knx/ets_calimero_group_name.xsl")));
        // Set the URIResolver
        transformer.setURIResolver(new EtsFileUriResolver(data));
        // Transform the source XML into byte array
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        transformer.transform(new StreamSource(zin), new StreamResult(bos));
        byte[] result = bos.toByteArray();
        // we use a map of state-based datapoints and read from the transformed xml
        final DatapointMap<StateDP> datapoints = new DatapointMap<>();
        try (final XmlReader r = XmlInputFactory.newInstance().createXMLStreamReader(new ByteArrayInputStream(result))) {
            datapoints.load(r);
        } catch (final KNXMLException e) {
            String msg = "Error loading parsed ETS file: " + e.getMessage();
            LOG.warning(msg);
            throw new IllegalStateException(msg, e);
        }
        MetaItem agentLink = AgentLink.asAgentLinkMetaItem(protocolConfiguration.getReferenceOrThrow());
        Map<String, Asset> createdAssets = new HashMap<>();
        for (StateDP dp : datapoints.getDatapoints()) {
            if (dp.getName().endsWith("#A")) {
                createAsset(dp, false, agentLink, createdAssets);
            } else if (dp.getName().endsWith("#S")) {
                createAsset(dp, true, agentLink, createdAssets);
            } else if (dp.getName().endsWith("#SA") || dp.getName().endsWith("#AS")) {
                createAsset(dp, false, agentLink, createdAssets);
                createAsset(dp, true, agentLink, createdAssets);
            } else {
                LOG.info("Only group addresses ending on #A, #S, #AS or #SA will be imported. Ignoring: " + dp.getName());
            }
        }
        return createdAssets.values().toArray(new Asset[createdAssets.values().size()]);
    } catch (Exception e) {
        throw new IllegalStateException("ETS import error", e);
    } finally {
        if (zin != null) {
            try {
                zin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
Also used : TransformerFactory(javax.xml.transform.TransformerFactory) Transformer(javax.xml.transform.Transformer) DatapointMap(tuwien.auto.calimero.datapoint.DatapointMap) StreamResult(javax.xml.transform.stream.StreamResult) ZipEntry(java.util.zip.ZipEntry) StreamSource(javax.xml.transform.stream.StreamSource) ByteArrayOutputStream(java.io.ByteArrayOutputStream) XmlReader(tuwien.auto.calimero.xml.XmlReader) KNXMLException(tuwien.auto.calimero.xml.KNXMLException) IOException(java.io.IOException) KNXMLException(tuwien.auto.calimero.xml.KNXMLException) KNXFormatException(tuwien.auto.calimero.KNXFormatException) IOException(java.io.IOException) KNXException(tuwien.auto.calimero.KNXException) ZipInputStream(java.util.zip.ZipInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) StateDP(tuwien.auto.calimero.datapoint.StateDP) Asset(org.openremote.model.asset.Asset)

Example 2 with XmlReader

use of tuwien.auto.calimero.xml.XmlReader in project openremote by openremote.

the class KNXProtocol method startAssetImport.

@Override
public Future<Void> startAssetImport(byte[] fileData, Consumer<AssetTreeNode[]> assetConsumer) {
    return executorService.submit(() -> {
        ZipInputStream zin = null;
        try {
            boolean fileFound = false;
            zin = new ZipInputStream(new ByteArrayInputStream(fileData));
            ZipEntry zipEntry = zin.getNextEntry();
            while (zipEntry != null) {
                if (zipEntry.getName().endsWith("/0.xml")) {
                    fileFound = true;
                    break;
                }
                zipEntry = zin.getNextEntry();
            }
            if (!fileFound) {
                String msg = "Failed to find '0.xml' in project file";
                LOG.info(msg);
                throw new IllegalStateException(msg);
            }
            // Create a transform factory instance.
            TransformerFactory tfactory = new net.sf.saxon.TransformerFactoryImpl();
            // Create a transformer for the stylesheet.
            InputStream inputStream = KNXProtocol.class.getResourceAsStream("/org/openremote/agent/protocol/knx/ets_calimero_group_name.xsl");
            String xsd = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
            // Get weird behaviour sometimes without this
            xsd = xsd.trim().replaceFirst("^([\\W]+)<", "<");
            LOG.warning(xsd);
            Transformer transformer = tfactory.newTransformer(new StreamSource(new StringReader(xsd)));
            // Set the URIResolver
            transformer.setURIResolver(new ETSFileURIResolver(fileData));
            // Transform the source XML
            String xml = IOUtils.toString(zin, StandardCharsets.UTF_8);
            // Get weird behaviour sometimes without this
            xml = xml.trim().replaceFirst("^([\\W]+)<", "<");
            LOG.warning(xml);
            StringWriter writer = new StringWriter();
            StringReader reader = new StringReader(xml);
            transformer.transform(new StreamSource(reader), new StreamResult(writer));
            xml = writer.toString();
            // we use a map of state-based data points and read from the transformed xml
            final DatapointMap<StateDP> datapoints = new DatapointMap<>();
            try (final XmlReader r = XmlInputFactory.newInstance().createXMLStreamReader(new StringReader(xml))) {
                datapoints.load(r);
            } catch (final KNXMLException e) {
                String msg = "Error loading parsed ETS file: " + e.getMessage();
                LOG.warning(msg);
                throw new IllegalStateException(msg, e);
            }
            Map<String, Asset<?>> createdAssets = new HashMap<>();
            for (StateDP dp : datapoints.getDatapoints()) {
                if (dp.getName().endsWith("#A")) {
                    createAsset(dp, false, createdAssets);
                } else if (dp.getName().endsWith("#S")) {
                    createAsset(dp, true, createdAssets);
                } else if (dp.getName().endsWith("#SA") || dp.getName().endsWith("#AS")) {
                    createAsset(dp, false, createdAssets);
                    createAsset(dp, true, createdAssets);
                } else {
                    LOG.info("Only group addresses ending on #A, #S, #AS or #SA will be imported. Ignoring: " + dp.getName());
                }
            }
            assetConsumer.accept(createdAssets.values().stream().map(AssetTreeNode::new).toArray(AssetTreeNode[]::new));
        } catch (Exception e) {
            LOG.log(Level.WARNING, "ETS import error", e);
        } finally {
            if (zin != null) {
                try {
                    zin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }, null);
}
Also used : Transformer(javax.xml.transform.Transformer) HashMap(java.util.HashMap) ZipEntry(java.util.zip.ZipEntry) StateDP(tuwien.auto.calimero.datapoint.StateDP) ThingAsset(org.openremote.model.asset.impl.ThingAsset) Asset(org.openremote.model.asset.Asset) TransformerFactory(javax.xml.transform.TransformerFactory) DatapointMap(tuwien.auto.calimero.datapoint.DatapointMap) StreamResult(javax.xml.transform.stream.StreamResult) ZipInputStream(java.util.zip.ZipInputStream) StreamSource(javax.xml.transform.stream.StreamSource) XmlReader(tuwien.auto.calimero.xml.XmlReader) KNXMLException(tuwien.auto.calimero.xml.KNXMLException) KNXMLException(tuwien.auto.calimero.xml.KNXMLException) KNXFormatException(tuwien.auto.calimero.KNXFormatException) AssetTreeNode(org.openremote.model.asset.AssetTreeNode) ZipInputStream(java.util.zip.ZipInputStream)

Aggregations

ZipEntry (java.util.zip.ZipEntry)2 ZipInputStream (java.util.zip.ZipInputStream)2 Transformer (javax.xml.transform.Transformer)2 TransformerFactory (javax.xml.transform.TransformerFactory)2 StreamResult (javax.xml.transform.stream.StreamResult)2 StreamSource (javax.xml.transform.stream.StreamSource)2 Asset (org.openremote.model.asset.Asset)2 KNXFormatException (tuwien.auto.calimero.KNXFormatException)2 DatapointMap (tuwien.auto.calimero.datapoint.DatapointMap)2 StateDP (tuwien.auto.calimero.datapoint.StateDP)2 KNXMLException (tuwien.auto.calimero.xml.KNXMLException)2 XmlReader (tuwien.auto.calimero.xml.XmlReader)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 AssetTreeNode (org.openremote.model.asset.AssetTreeNode)1 ThingAsset (org.openremote.model.asset.impl.ThingAsset)1 KNXException (tuwien.auto.calimero.KNXException)1