View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.template.xmlanon;
28  
29  import com.rapiddweller.benerator.template.TemplateInputReader;
30  import com.rapiddweller.common.Assert;
31  import com.rapiddweller.common.ConfigurationError;
32  import com.rapiddweller.common.Context;
33  import com.rapiddweller.common.IOUtil;
34  import com.rapiddweller.common.ParseException;
35  import com.rapiddweller.common.StringUtil;
36  import com.rapiddweller.format.xls.XLSUtil;
37  import org.apache.poi.ss.usermodel.Cell;
38  import org.apache.poi.ss.usermodel.Row;
39  import org.apache.poi.ss.usermodel.Sheet;
40  import org.apache.poi.ss.usermodel.Workbook;
41  import org.apache.poi.ss.usermodel.WorkbookFactory;
42  
43  import java.io.IOException;
44  import java.util.ArrayList;
45  import java.util.List;
46  
47  /**
48   * Reads XLS documents for a multi-file XML anonymization.<br/><br/>
49   * Created: 06.03.2014 08:25:43
50   *
51   * @author Volker Bergmann
52   * @since 0.9.0
53   */
54  public class XmlAnonInputReader implements TemplateInputReader {
55  
56    @Override
57    public void parse(String uri, Context context) throws IOException, ParseException {
58      AnonymizationSetup setup = parseXls(uri);
59      verifyXMLFileSettings(setup);
60      context.set("setup", setup);
61    }
62  
63    private static AnonymizationSetup parseXls(String xlsUri) throws IOException {
64      Workbook workbook = WorkbookFactory.create(IOUtil.getInputStreamForURI(xlsUri));
65      Sheet sheet = workbook.getSheetAt(0);
66  
67      // parse header information
68      int varnameColumnIndex = -1;
69      ArrayList<String> files = new ArrayList<>();
70      Row headerRow = sheet.getRow(0);
71      Assert.notNull(headerRow, "header row");
72      for (int i = 0; i <= headerRow.getLastCellNum(); i++) {
73        String header = headerRow.getCell(i).getStringCellValue();
74        if ("varname".equals(header)) {
75          varnameColumnIndex = i;
76          break;
77        } else {
78          if (StringUtil.isEmpty(header)) {
79            throw new ConfigurationError("Filename missing in column header #" + i + " of Excel document " + xlsUri);
80          }
81          files.add(header);
82        }
83      }
84      if (varnameColumnIndex == -1) {
85        throw new ConfigurationError("No 'varname' header defined in Excel document " + xlsUri);
86      }
87      if (files.size() == 0) {
88        throw new ConfigurationError("No files specified in Excel document " + xlsUri);
89      }
90  
91      // parse anonymization rows
92      List<Anonymization> anonymizations = new ArrayList<>();
93      for (int rownum = 1; rownum <= sheet.getLastRowNum(); rownum++) {
94        Row row = sheet.getRow(rownum);
95        if (XLSUtil.isEmpty(row)) {
96          continue;
97        }
98        Cell varnameCell = row.getCell(varnameColumnIndex);
99        if (varnameCell == null || StringUtil.isEmpty(varnameCell.getStringCellValue())) {
100         throw new ConfigurationError("'varname' cell empty in table row #" + (rownum + 1));
101       }
102       Anonymizationplate/xmlanon/Anonymization.html#Anonymization">Anonymization anon = new Anonymization(varnameCell.getStringCellValue());
103       // parse locators
104       for (int colnum = 0; colnum < varnameColumnIndex; colnum++) {
105         Cell cell = row.getCell(colnum);
106         String path = (cell != null ? cell.getStringCellValue() : null);
107         if (!StringUtil.isEmpty(path)) {
108           List<String> tokens = XPathTokenizer.tokenize(path);
109           String entityPath = XPathTokenizer.merge(tokens, 0, tokens.size() - 2);
110           String entity = normalizeXMLPath(XPathTokenizer.nodeName(tokens.get(tokens.size() - 2)));
111           String attribute = normalizeXMLPath(tokens.get(tokens.size() - 1));
112           anon.addLocator(new Locator(files.get(colnum), path, entityPath, entity, attribute));
113         }
114       }
115       // parse settings
116       for (int colnum = varnameColumnIndex + 1; colnum < row.getLastCellNum() - 1; colnum += 2) {
117         String key = row.getCell(colnum).getStringCellValue();
118         String value = row.getCell(colnum + 1).getStringCellValue();
119         if (!StringUtil.isEmpty(key) && !StringUtil.isEmpty(value)) {
120           anon.addSetting(key, value);
121         }
122       }
123       anonymizations.add(anon);
124     }
125     return new AnonymizationSetup(files, anonymizations);
126   }
127 
128   private static void verifyXMLFileSettings(AnonymizationSetup setup) {
129     for (String file : setup.getFiles()) {
130       if (StringUtil.isEmpty(System.getProperty(file))) {
131         throw new ConfigurationError("No concrete file specified for file variable " + file);
132       }
133     }
134   }
135 
136   private static String normalizeXMLPath(String path) {
137     return path.replace('.', '_').replace('-', '_');
138   }
139 
140 }