1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest.mrep;
  28 
  29 import java.io.File;
  30 import java.io.IOException;
  31 import java.util.ArrayList;
  32 import java.util.HashMap;
  33 import java.util.HashSet;
  34 import java.util.Iterator;
  35 import java.util.List;
  36 import java.util.Map;
  37 import java.util.Set;
  38 
  39 import javax.xml.parsers.ParserConfigurationException;
  40 
  41 import org.xml.sax.SAXException;
  42 
  43 class Merger {
  44 
  45     /**
  46      * @param in array of files with XML reports
  47      * @param out file to put results
  48      * @param conflictResolver ConflictResolver to resolve conflicts during merge
  49      */
  50     public boolean merge(File[] in, File out, ConflictResolver conflictResolver) throws SAXException,
  51             ParserConfigurationException, IOException{
  52         // Maps with statistics
  53         Map<?, ?>[] inputs = new Map<?, ?>[in.length];
  54         // read statistics
  55         for (int i = 0; i < in.length; i++) {
  56             XMLReportReader reader = new XMLReportReader();
  57             Map<?, ?> map = reader.readIDs(in[i]);
  58             inputs[i] = map;
  59         }
  60 
  61         // shift word workgroups id renaming
  62         int allCnt = 0;
  63         // rename id's and find conflicts
  64         Set<String> all = new HashSet<>();
  65         List<String> conflicts = new ArrayList<>();
  66         for (int i = 0; i < in.length; i++) {
  67             int workdirsInFile = 0;
  68             Iterator<?> it = inputs[i].keySet().iterator();
  69             Map<Object, Object> newMap = new HashMap<>();
  70             while (it.hasNext()) {
  71                 Object o =  it.next();
  72                 // this is workdir ID
  73                 if (o instanceof Integer) {
  74                     Integer id = (Integer) o;
  75                     Integer nid = new Integer(id.intValue() + allCnt);
  76                     newMap.put(id, nid);
  77                     workdirsInFile++;
  78                 }
  79                 // this is test result url
  80                 if (o instanceof String) {
  81                     String url = (String) o;
  82                     if (all.contains(url) && !conflicts.contains(url)) {
  83                         conflicts.add(url);
  84                     }
  85                     all.add(url);
  86                     TestResultDescr td = (TestResultDescr)inputs[i].get(o);
  87                     td.setID(td.getID() + allCnt);
  88                     newMap.put(url, td);
  89                 }
  90 
  91             }
  92             inputs[i] = newMap;
  93             allCnt += workdirsInFile;
  94         }
  95 
  96         // resolve each conflict
  97         for (int c = 0; c < conflicts.size(); c++) {
  98             String url = conflicts.get(c);
  99             List<TestResultDescr> tds = new ArrayList<>();
 100             for(int i = 0; i < in.length; i++) {
 101                 TestResultDescr td = (TestResultDescr) inputs[i].get(url);
 102                 if (td != null) {
 103                     td.setFile(in[i]);
 104                     tds.add(td);
 105                 }
 106             }
 107             TestResultDescr[] tda = tds.toArray(new TestResultDescr[0]);
 108             int res = conflictResolver.resolve(url, tda);
 109             if (res < 0) {
 110                 // cancel
 111                 return false;
 112             }
 113             for(int i = 0; i < in.length; i++) {
 114                 if (!in[i].equals(tda[res].getFile())) {
 115                     TestResultDescr td = (TestResultDescr)inputs[i].get(url);
 116                     if (td != null) {
 117                         td.setID(-1);
 118                     }
 119                 }
 120             }
 121         }
 122 
 123         // make merge with using statistics
 124         new XMLReportWriter(out).write(in, inputs);
 125         return true;
 126     }
 127 }