/* * ARX: Powerful Data Anonymization * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors * * Licensed 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.deidentifier.arx.gui.worker; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.lang.reflect.InvocationTargetException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import org.deidentifier.arx.ARXAnonymizer; import org.deidentifier.arx.ARXConfiguration; import org.deidentifier.arx.ARXLattice; import org.deidentifier.arx.ARXLattice.ARXNode; import org.deidentifier.arx.ARXLattice.Anonymity; import org.deidentifier.arx.ARXResult; import org.deidentifier.arx.AttributeType; import org.deidentifier.arx.AttributeType.Hierarchy; import org.deidentifier.arx.AttributeType.MicroAggregationFunction; import org.deidentifier.arx.Data; import org.deidentifier.arx.DataDefinition; import org.deidentifier.arx.DataType; import org.deidentifier.arx.DataType.DataTypeDescription; import org.deidentifier.arx.framework.lattice.SolutionSpace; import org.deidentifier.arx.gui.Controller; import org.deidentifier.arx.gui.model.Model; import org.deidentifier.arx.gui.model.ModelConfiguration; import org.deidentifier.arx.gui.model.ModelNodeFilter; import org.deidentifier.arx.gui.model.ModelTransformationMode; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.worker.io.Vocabulary; import org.deidentifier.arx.gui.worker.io.Vocabulary_V2; import org.deidentifier.arx.gui.worker.io.XMLHandler; import org.deidentifier.arx.metric.InformationLoss; import org.deidentifier.arx.metric.Metric; import org.eclipse.core.runtime.IProgressMonitor; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; /** * This worker loads a project file from disk. * * @author Fabian Prasser */ public class WorkerLoad extends Worker<Model> { /** The vocabulary to use. */ private Vocabulary vocabulary = null; /** The zip file. */ private ZipFile zipfile; /** The lattice. */ private ARXLattice lattice; /** The model. */ private Model model; /** * Creates a new instance. * * @param file * @param controller * @throws ZipException * @throws IOException */ public WorkerLoad(final File file, final Controller controller) throws ZipException, IOException { this.zipfile = new ZipFile(file); } /** * Constructor. * * @param path * @param controller * @throws IOException */ public WorkerLoad(final String path, final Controller controller) throws IOException { this.zipfile = new ZipFile(path); } @Override public void run(final IProgressMonitor arg0) throws InvocationTargetException, InterruptedException { arg0.beginTask(Resources.getMessage("WorkerLoad.2"), 8); //$NON-NLS-1$ try { final ZipFile zip = zipfile; readMetadata(zip); arg0.worked(1); readModel(zip); arg0.worked(1); final Map<String, ARXNode> map = readLattice(zip); arg0.worked(1); readClipboard(map, zip); arg0.worked(1); readFilter(zip); arg0.worked(1); readConfiguration(map, zip); arg0.worked(1); setMonotonicity(); zip.close(); arg0.worked(1); } catch (final Exception e) { error = e; arg0.done(); return; } result = model; arg0.worked(1); arg0.done(); } /** * Reads the clipboard from the file. * * @param map * @param zip * @throws SAXException * @throws IOException */ private void readClipboard(final Map<String, ARXNode> map, final ZipFile zip) throws SAXException, IOException { // Check final ZipEntry entry = zip.getEntry("clipboard.xml"); //$NON-NLS-1$ if (entry == null) { return; } // Clear model.getClipboard().clearClipboard(); // Parse final XMLReader xmlReader = XMLReaderFactory.createXMLReader(); final InputSource inputSource = new InputSource(new BufferedInputStream(zip.getInputStream(entry))); xmlReader.setContentHandler(new XMLHandler() { @Override protected boolean end(final String uri, final String localName, final String qName) throws SAXException { if (vocabulary.isClipboard(localName)) { return true; } else if (vocabulary.isNode(localName)) { if (payload == null || map == null) return true; final ARXNode node = map.get(payload.trim()); model.getClipboard().addToClipboard(node); return true; } else { return false; } } @Override protected boolean start(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { if (vocabulary.isClipboard(localName) || vocabulary.isNode(localName)) { return true; } else { return false; } } }); xmlReader.parse(inputSource); } /** * Reads the configuration from the file. * * @param map * @param zip * @throws IOException * @throws ClassNotFoundException * @throws SAXException */ private void readConfiguration(final Map<String, ARXNode> map, final ZipFile zip) throws IOException, ClassNotFoundException, SAXException { readConfiguration("input/", false, map, zip); //$NON-NLS-1$ readConfiguration("output/", true, map, zip); //$NON-NLS-1$ } /** * Reads the configuration from the file. * * @param prefix * @param output * @param map * @param zip * @throws IOException * @throws ClassNotFoundException * @throws SAXException */ @SuppressWarnings("deprecation") private void readConfiguration(final String prefix, final boolean output, final Map<String, ARXNode> map, final ZipFile zip) throws IOException, ClassNotFoundException, SAXException { // Check final ZipEntry entry = zip.getEntry(prefix + "config.dat"); //$NON-NLS-1$ if (entry == null) { return; } // Read config final ObjectInputStream oos = new ObjectInputStream(new BufferedInputStream(zip.getInputStream(entry))); final ModelConfiguration config = (ModelConfiguration) oos.readObject(); // Convert metric from v1 to v2 config.setMetric(Metric.createMetric(config.getMetric(), ARXLattice.getDeserializationContext().minLevel, ARXLattice.getDeserializationContext().maxLevel)); config.getConfig().setQualityModel(Metric.createMetric(config.getConfig().getQualityModel(), ARXLattice.getDeserializationContext().minLevel, ARXLattice.getDeserializationContext().maxLevel)); oos.close(); // Attach data if (!output) { // Read input, config and definition readInput(config, zip); model.setInputConfig(config); readDefinition(config, output, model.getInputDefinition(), prefix, zip); // TODO: Needed for backwards compatibility of ARX 3.4.0 with previous versions if (model.getInputConfig().getInput() != null && model.getInputPopulationModel() != null) { model.getInputPopulationModel().makeBackwardsCompatible(config.getInput().getHandle().getNumRows()); } } else { // Read input, config and definition config.setInput(model.getInputConfig().getInput()); model.setOutputConfig(config); DataDefinition definition = new DataDefinition(); readDefinition(config, output, definition, prefix, zip); // Create Handles final int historySize = model.getHistorySize(); final double snapshotSizeSnapshot = model.getSnapshotSizeSnapshot(); final double snapshotSizeDataset = model.getSnapshotSizeDataset(); final Metric<?> metric = config.getMetric(); final long time = model.getTime(); final ARXNode optimalNode; final ARXNode outputNode; if (model.getOptimalNodeAsString() != null) { optimalNode = map.get(model.getOptimalNodeAsString()); } else { optimalNode = null; } if (model.getOutputNodeAsString() != null) { outputNode = map.get(model.getOutputNodeAsString()); } else { outputNode = null; } model.setSelectedNode(outputNode); // Create solution space ARXConfiguration arxconfig = model.getOutputConfig().getConfig(); SolutionSpace solutions = new SolutionSpace(lattice, arxconfig); // Update model model.setResult(new ARXResult(config.getInput().getHandle(), definition, lattice, historySize, snapshotSizeSnapshot, snapshotSizeDataset, metric, arxconfig, optimalNode, time, solutions)); // Update lattice ARXLattice lattice = model.getResult().getLattice(); if (lattice != null) { lattice.access().setSolutionSpace(solutions); } // Create anonymizer final ARXAnonymizer f = new ARXAnonymizer(); model.setAnonymizer(f); f.setHistorySize(historySize); f.setMaximumSnapshotSizeSnapshot(snapshotSizeSnapshot); f.setMaximumSnapshotSizeDataset(snapshotSizeDataset); } } /** * Reads the data definition from the file. * * @param config * @param output * @param definition * @param prefix * @param zip * @throws IOException * @throws SAXException */ private void readDefinition(final ModelConfiguration config, final boolean output, final DataDefinition definition, final String prefix, final ZipFile zip) throws IOException, SAXException { // Obtain entry final ZipEntry entry = zip.getEntry(prefix + "definition.xml"); //$NON-NLS-1$ if (entry == null) { return; } // Read xml final XMLReader xmlReader = XMLReaderFactory.createXMLReader(); final InputSource inputSource = new InputSource(new BufferedInputStream(zip.getInputStream(entry))); xmlReader.setContentHandler(new XMLHandler() { String attr, dtype, atype, ref, min, max, format; @Override protected boolean end(final String uri, final String localName, final String qName) throws SAXException { if (vocabulary.isDefinition(localName)) { return true; } else if (vocabulary.isAssigment(localName)) { // Attribute name if (attr == null) { throw new SAXException(Resources.getMessage("WorkerLoad.3")); } //$NON-NLS-1$ // TODO: For backwards compatibility only if (vocabulary.getVocabularyVersion().equals("1.0")) { //$NON-NLS-1$ // Data type if (dtype.equals(DataType.STRING.toString())) { definition.setDataType(attr, DataType.STRING); } else if (dtype.equals(DataType.DECIMAL.toString())) { definition.setDataType(attr, DataType.DECIMAL); } else { definition.setDataType(attr, DataType.createDate(dtype)); } } else if (vocabulary.getVocabularyVersion().equals("2.0")) { //$NON-NLS-1$ // Find matching data type DataType<?> datatype = null; for (DataTypeDescription<?> description : DataType.list()) { if (description.getLabel().equals(dtype)){ // Check format if (format != null){ if (!description.hasFormat()) { throw new RuntimeException(Resources.getMessage("WorkerLoad.14")); //$NON-NLS-1$ } datatype = description.newInstance(format); } else { datatype = description.newInstance(); } break; } } // Check if found if (datatype == null){ throw new RuntimeException(Resources.getMessage("WorkerLoad.15")+attr); //$NON-NLS-1$ } // Store definition.setDataType(attr, datatype); } // Attribute type if (atype.equals(AttributeType.IDENTIFYING_ATTRIBUTE.toString())) { definition.setAttributeType(attr, AttributeType.IDENTIFYING_ATTRIBUTE); } else if (atype.equals(AttributeType.SENSITIVE_ATTRIBUTE.toString())) { definition.setAttributeType(attr, AttributeType.SENSITIVE_ATTRIBUTE); if (ref != null){ try { /*For backwards compatibility*/ if (config.getHierarchy(attr) == null) { config.setHierarchy(attr, readHierarchy(zip, prefix, ref)); } } catch (final IOException e) { throw new SAXException(e); } } } else if (atype.equals(AttributeType.INSENSITIVE_ATTRIBUTE.toString())) { definition.setAttributeType(attr, AttributeType.INSENSITIVE_ATTRIBUTE); } else if (atype.equals(AttributeType.QUASI_IDENTIFYING_ATTRIBUTE.toString())) { definition.setAttributeType(attr, AttributeType.QUASI_IDENTIFYING_ATTRIBUTE); if (config.getTransformationMode(attr) == ModelTransformationMode.MICRO_AGGREGATION) { MicroAggregationFunction microaggregation = config.getMicroAggregationFunction(attr).createInstance(config.getMicroAggregationIgnoreMissingData(attr)); definition.setMicroAggregationFunction(attr, microaggregation); } Hierarchy hierarchy = config.getHierarchy(attr); /* For backwards compatibility */ if (hierarchy == null) { // Check if a hierarchy is defined in the XML file if (ref != null) { try { // Bugfix: ARX 3.4.1 does not serialize automatically created empty hierarchies // but it does create a reference to such a file. We handle this case separately now // which probably breaks the backwards compatibility to older versions of ARX for // which this clodeblock was initially implemented: if (output && zip.getEntry(prefix + ref) == null) { // Create an empty hierarchy String[] data = config.getInput().getHandle().getDistinctValues(config.getInput() .getHandle() .getColumnIndexOf(attr)); String[][] array = new String[data.length][]; for (int i=0; i<data.length; i++) { array[i] = new String[]{data[i]}; } hierarchy = Hierarchy.create(array); } else { hierarchy = readHierarchy(zip, prefix, ref); } } catch (final IOException e) { throw new SAXException(e); } } } // Only if a hierarchy has been defined if (hierarchy != null && hierarchy.getHierarchy() != null) { config.setHierarchy(attr, hierarchy); /* For backwards compatibility */ definition.setHierarchy(attr, hierarchy); int height = hierarchy.getHierarchy().length > 0 ? hierarchy.getHierarchy()[0].length : 0; if (min.equals("All")) { //$NON-NLS-1$ config.setMinimumGeneralization(attr, null); definition.setMinimumGeneralization(attr, 0); } else { config.setMinimumGeneralization(attr, Integer.valueOf(min)); definition.setMinimumGeneralization(attr, Integer.valueOf(min)); } if (max.equals("All")) { //$NON-NLS-1$ config.setMaximumGeneralization(attr, null); definition.setMaximumGeneralization(attr, height - 1); } else { config.setMaximumGeneralization(attr, Integer.valueOf(max)); definition.setMaximumGeneralization(attr, Integer.valueOf(max)); } // TODO: For backwards compatibility only if (vocabulary.getVocabularyVersion().equals("1.0")) { //$NON-NLS-1$ if (config.getMinimumGeneralization(attr) != null && config.getMinimumGeneralization(attr).equals(0)) { config.setMinimumGeneralization(attr, null); } if (config.getMaximumGeneralization(attr) != null && config.getMaximumGeneralization(attr).equals(height - 1)) { config.setMaximumGeneralization(attr, null); } } } } else { throw new SAXException(Resources.getMessage("WorkerLoad.4")); //$NON-NLS-1$ } attr = null; atype = null; dtype = null; ref = null; min = null; max = null; format = null; return true; } else if (vocabulary.isName(localName)) { attr = payload; return true; } else if (vocabulary.isType(localName)) { atype = payload; return true; } else if (vocabulary.isDatatype(localName)) { dtype = payload; return true; } else if (vocabulary.isFormat(localName)) { format = payload; return true; } else if (vocabulary.isRef(localName)) { ref = payload; return true; } else if (vocabulary.isMin(localName)) { min = payload; return true; } else if (vocabulary.isMax(localName)) { max = payload; return true; } else if (vocabulary.isMicroaggregationFunction(localName)) { // Ignore return true; } else if (vocabulary.isMicroaggregationIgnoreMissingData(localName)) { // Ignore return true; } else { return false; } } @Override protected boolean start(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { if (vocabulary.isDefinition(localName)) { return true; } else if (vocabulary.isAssigment(localName)) { attr = null; dtype = null; atype = null; ref = null; min = null; max = null; return true; } else if (vocabulary.isName(localName) || vocabulary.isType(localName) || vocabulary.isDatatype(localName) || vocabulary.isFormat(localName) || vocabulary.isRef(localName) || vocabulary.isMin(localName) || vocabulary.isMax(localName) || vocabulary.isMicroaggregationFunction(localName) || vocabulary.isMicroaggregationIgnoreMissingData(localName)) { return true; } else { return false; } } }); xmlReader.parse(inputSource); } /** * Reads the filter from the file. * * @param zip * @throws SAXException * @throws IOException * @throws ClassNotFoundException */ private void readFilter(final ZipFile zip) throws SAXException, IOException, ClassNotFoundException { // Read filter final ZipEntry entry = zip.getEntry("filter.dat"); //$NON-NLS-1$ if (entry == null) { return; } final ObjectInputStream oos = new ObjectInputStream(new BufferedInputStream(zip.getInputStream(entry))); model.setNodeFilter((ModelNodeFilter) oos.readObject()); oos.close(); } /** * Reads the hierarchy from the given location. * * @param zip * @param prefix * @param ref * @return * @throws IOException */ private Hierarchy readHierarchy(final ZipFile zip, final String prefix, final String ref) throws IOException { final ZipEntry entry = zip.getEntry(prefix + ref); if (entry == null) { throw new IOException(Resources.getMessage("WorkerLoad.5")); } //$NON-NLS-1$ final InputStream is = new BufferedInputStream(zip.getInputStream(entry)); // Use project delimiter for backwards compatibility return Hierarchy.create(is, Charset.defaultCharset(), model.getCSVSyntax().getDelimiter()); } /** * Reads the input from the file. * * @param config * @param zip * @throws IOException */ private void readInput(final ModelConfiguration config, final ZipFile zip) throws IOException { final ZipEntry entry = zip.getEntry("data/input.csv"); //$NON-NLS-1$ if (entry == null) { return; } // Read input // Use project delimiter for backwards compatibility config.setInput(Data.create(new BufferedInputStream(zip.getInputStream(entry)), Charset.defaultCharset(), model.getCSVSyntax().getDelimiter())); // Disable visualization if (model.getMaximalSizeForComplexOperations() > 0 && config.getInput().getHandle().getNumRows() > model.getMaximalSizeForComplexOperations()) { model.setVisualizationEnabled(false); } // And encode config.getInput().getHandle(); } /** * Reads the lattice from several files. * * @param zip * @return * @throws IOException * @throws ClassNotFoundException * @throws SAXException */ @SuppressWarnings({ "unchecked" }) private Map<String, ARXNode> readLattice(final ZipFile zip) throws IOException, ClassNotFoundException, SAXException { ZipEntry entry = zip.getEntry("infoloss.dat"); //$NON-NLS-1$ if (entry == null) { return null; } // Read infoloss final Map<Integer, InformationLoss<?>> max; final Map<Integer, InformationLoss<?>> min; ObjectInputStream oos = new ObjectInputStream(new BufferedInputStream(zip.getInputStream(entry))); min = (Map<Integer, InformationLoss<?>>) oos.readObject(); max = (Map<Integer, InformationLoss<?>>) oos.readObject(); oos.close(); // Create deserialization context final int[] minMax = readMinMax(zip); ARXLattice.getDeserializationContext().minLevel = minMax[0]; ARXLattice.getDeserializationContext().maxLevel = minMax[1]; // Read attributes entry = zip.getEntry("attributes.dat"); //$NON-NLS-1$ if (entry == null) { throw new IOException(Resources.getMessage("WorkerLoad.6")); } //$NON-NLS-1$ // Read attributes final Map<Integer, Map<Integer, Object>> attrs; oos = new ObjectInputStream(new BufferedInputStream(zip.getInputStream(entry))); attrs = (Map<Integer, Map<Integer, Object>>) oos.readObject(); oos.close(); // Read lattice skeleton entry = zip.getEntry("lattice.dat"); //$NON-NLS-1$ if (entry == null) { throw new IOException(Resources.getMessage("WorkerLoad.8")); } //$NON-NLS-1$ oos = new ObjectInputStream(new BufferedInputStream(zip.getInputStream(entry))); lattice = (ARXLattice) oos.readObject(); final Map<String, Integer> headermap = (Map<String, Integer>) oos.readObject(); oos.close(); final Map<Integer, List<ARXNode>> levels = new HashMap<Integer, List<ARXNode>>(); // Read the lattice for the first time entry = zip.getEntry("lattice.xml"); //$NON-NLS-1$ if (entry == null) { throw new IOException(Resources.getMessage("WorkerLoad.7")); } //$NON-NLS-1$ final Map<Integer, ARXNode> map = new HashMap<Integer, ARXNode>(); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); InputSource inputSource = new InputSource(new BufferedInputStream(zip.getInputStream(entry))); xmlReader.setContentHandler(new XMLHandler() { private int level = 0; private int id = 0; private int[] transformation; private Anonymity anonymity; private boolean checked; @Override protected boolean end(final String uri, final String localName, final String qName) throws SAXException { if (vocabulary.isLattice(localName) || vocabulary.isLevel(localName) || vocabulary.isPredecessors(localName) || vocabulary.isSuccessors(localName) || vocabulary.isInfoloss(localName) || vocabulary.isMax2(localName) || vocabulary.isMin2(localName)) { return true; } else if (vocabulary.isNode2(localName)) { final ARXNode node = lattice.new ARXNode(lattice); node.access().setAnonymity(anonymity); node.access().setChecked(checked); node.access().setTransformation(transformation); node.access().setHighestScore(max.get(id)); node.access().setLowestScore(min.get(id)); node.access().setAttributes(attrs.get(id)); node.access().setHeadermap(headermap); levels.get(level).add(node); map.put(id, node); return true; } else if (vocabulary.isTransformation(localName)) { transformation = readTransformation(payload); return true; } else if (vocabulary.isAnonymity(localName)) { anonymity = Anonymity.valueOf(payload); return true; } else if (vocabulary.isChecked(localName)) { checked = Boolean.valueOf(payload); return true; } else { return false; } } @Override protected boolean start(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { if (vocabulary.isLattice(localName)) { return true; } else if (vocabulary.isLevel(localName)) { level = Integer.valueOf(attributes.getValue(vocabulary.getDepth())); if (!levels.containsKey(level)) { levels.put(level, new ArrayList<ARXNode>()); } return true; } else if (vocabulary.isNode2(localName)) { id = Integer.valueOf(attributes.getValue(vocabulary.getId())); return true; } else if (vocabulary.isTransformation(localName) || vocabulary.isAnonymity(localName) || vocabulary.isChecked(localName) || vocabulary.isPredecessors(localName) || vocabulary.isSuccessors(localName) || vocabulary.isInfoloss(localName) || vocabulary.isMax2(localName) || vocabulary.isMin2(localName)) { return true; } else { return false; } } }); xmlReader.parse(inputSource); // Read the lattice for the second time entry = zip.getEntry("lattice.xml"); //$NON-NLS-1$ xmlReader = XMLReaderFactory.createXMLReader(); inputSource = new InputSource(new BufferedInputStream(zip.getInputStream(entry))); xmlReader.setContentHandler(new XMLHandler() { private int id; private final List<ARXNode> predecessors = new ArrayList<ARXNode>(); private final List<ARXNode> successors = new ArrayList<ARXNode>(); @Override protected boolean end(final String uri, final String localName, final String qName) throws SAXException { if (vocabulary.isLattice(localName)) { return true; } else if (vocabulary.isLevel(localName)) { return true; } else if (vocabulary.isNode2(localName)) { map.get(id) .access() .setPredecessors(predecessors.toArray(new ARXNode[predecessors.size()])); map.get(id) .access() .setSuccessors(successors.toArray(new ARXNode[successors.size()])); return true; } else if (vocabulary.isTransformation(localName) || vocabulary.isAnonymity(localName) || vocabulary.isChecked(localName) || vocabulary.isInfoloss(localName) || vocabulary.isMax2(localName) || vocabulary.isMin2(localName)) { return true; } else if (vocabulary.isPredecessors(localName)) { final String[] a = payload.trim().split(","); //$NON-NLS-1$ for (final String s : a) { final String b = s.trim(); if (!b.equals("")) { //$NON-NLS-1$ predecessors.add(map.get(Integer.valueOf(b))); } } return true; } else if (vocabulary.isSuccessors(localName)) { final String[] a = payload.trim().split(","); //$NON-NLS-1$ for (final String s : a) { final String b = s.trim(); if (!b.equals("")) { //$NON-NLS-1$ successors.add(map.get(Integer.valueOf(b))); } } return true; } else if (vocabulary.isAttribute(localName)) { return true; } else { return false; } } @Override protected boolean start(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { if (vocabulary.isNode2(localName)) { id = Integer.valueOf(attributes.getValue(vocabulary.getId())); successors.clear(); predecessors.clear(); return true; } else if (vocabulary.isTransformation(localName) || vocabulary.isLattice(localName) || vocabulary.isLevel(localName) || vocabulary.isAnonymity(localName) || vocabulary.isChecked(localName) || vocabulary.isPredecessors(localName) || vocabulary.isSuccessors(localName) || vocabulary.isAttribute(localName) || vocabulary.isInfoloss(localName) || vocabulary.isMax2(localName) || vocabulary.isMin2(localName)) { return true; } else { return false; } } }); xmlReader.parse(inputSource); // Set lattice int bottomLevel = Integer.MAX_VALUE; final ARXNode[][] llevels = new ARXNode[levels.size()][]; for (final Entry<Integer, List<ARXNode>> e : levels.entrySet()) { llevels[e.getKey()] = e.getValue().toArray(new ARXNode[] {}); if (!e.getValue().isEmpty()) { bottomLevel = Math.min(e.getKey(), bottomLevel); } } lattice.access().setLevels(llevels); lattice.access().setBottom(llevels[bottomLevel][0]); lattice.access().setTop(llevels[llevels.length - 1][0]); // Return the map final Map<String, ARXNode> result = new HashMap<String, ARXNode>(); for (final List<ARXNode> e : levels.values()) { for (final ARXNode node : e) { result.put(Arrays.toString(node.getTransformation()), node); } } return result; } /** * Reads the metadata from the file. * * @param zip * @throws IOException * @throws SAXException */ private void readMetadata(final ZipFile zip) throws IOException, SAXException { final ZipEntry entry = zip.getEntry("metadata.xml"); //$NON-NLS-1$ if (entry == null) { throw new IOException(Resources.getMessage("WorkerLoad.9")); } //$NON-NLS-1$ // Read vocabulary final XMLReader xmlReader = XMLReaderFactory.createXMLReader(); final InputSource inputSource = new InputSource(new BufferedInputStream(zip.getInputStream(entry))); xmlReader.setContentHandler(new XMLHandler() { Vocabulary_V2 vocabulary = new Vocabulary_V2(); String version = null; String vocabularyVersion = null; @Override protected boolean end(final String uri, final String localName, final String qName) throws SAXException { if (vocabulary.isMetadata(localName)) { if (vocabularyVersion == null){ vocabularyVersion = "1.0"; } //$NON-NLS-1$ WorkerLoad.this.vocabulary = Vocabulary.forVersion(vocabularyVersion); WorkerLoad.this.vocabulary.checkVersion(version); } else if (vocabulary.isVersion(localName)) { version = payload; } else if (vocabulary.isVocabulary(localName)) { vocabularyVersion = payload; } else { return false; } return true; } @Override protected boolean start(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { if (vocabulary.isMetadata(localName) || vocabulary.isVersion(localName) || vocabulary.isVocabulary(localName)) { return true; } else { return false; } } }); xmlReader.parse(inputSource); } /** * Reads min & max generalization levels, if any. * * @param zip * @return * @throws SAXException * @throws IOException */ private int[] readMinMax(final ZipFile zip) throws SAXException, IOException { // Read the lattice ZipEntry entry = zip.getEntry("lattice.xml"); //$NON-NLS-1$ if (entry == null) { return new int[]{0,0}; } // The result final int[] result = new int[]{Integer.MAX_VALUE, 0}; // Read XMLReader xmlReader = XMLReaderFactory.createXMLReader(); InputSource inputSource = new InputSource(new BufferedInputStream(zip.getInputStream(entry))); xmlReader.setContentHandler(new XMLHandler() { @Override protected boolean end(final String uri, final String localName, final String qName) throws SAXException { return true; } @Override protected boolean start(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException { if (vocabulary.isLevel(localName)) { int level = Integer.valueOf(attributes.getValue(vocabulary.getDepth())); result[0] = Math.min(result[0], level); result[1] = Math.max(result[1], level); } return true; } }); // Parse xmlReader.parse(inputSource); // Result return result; } /** * Reads the project from the file. * * @param zip * @throws IOException * @throws ClassNotFoundException */ private void readModel(final ZipFile zip) throws IOException, ClassNotFoundException { final ZipEntry entry = zip.getEntry("project.dat"); //$NON-NLS-1$ if (entry == null) { throw new IOException(Resources.getMessage("WorkerLoad.11")); } //$NON-NLS-1$ // Read model final ObjectInputStream oos = new ObjectInputStream(new BufferedInputStream(zip.getInputStream(entry))); model = (Model) oos.readObject(); oos.close(); } /** * Reads a transformation from the serialized array representation. * * @param payload * @return */ private int[] readTransformation(final String payload) { final String[] a = payload.split("\\[|,|\\]"); //$NON-NLS-1$ final int[] r = new int[a.length - 1]; for (int i = 1; i < a.length; i++) { r[i - 1] = Integer.valueOf(a[i].trim()); } return r; } /** * Fix monotonicity for backwards compatibility. */ private void setMonotonicity() { if (lattice != null && model != null && model.getOutputConfig() != null && model.getOutputConfig().getConfig() != null) { lattice.access().setMonotonicity(model.getOutputConfig().getConfig()); } } }