EMMA Coverage Report (generated Sat Nov 03 21:53:04 GMT 2007)
[all classes][sf.qof.parser]

COVERAGE SUMMARY FOR SOURCE FILE [PartialDefinitionCombiner.java]

nameclass, %method, %block, %line, %
PartialDefinitionCombiner.java67%  (2/3)88%  (7/8)95%  (365/384)94%  (82.7/88)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PartialDefinitionCombiner100% (1/1)80%  (4/5)99%  (315/318)97%  (67/69)
PartialDefinitionCombiner (): void 0%   (0/1)0%   (0/3)0%   (0/2)
combine (List): List 100% (1/1)100% (224/224)100% (50/50)
makeEmptyIfNull (String): String 100% (1/1)100% (6/6)100% (1/1)
numberOfParts (List, int): int 100% (1/1)100% (49/49)100% (8/8)
validatePartialDefinitions (List): void 100% (1/1)100% (36/36)100% (8/8)
     
class PartialDefinitionCombiner$10%   (0/1)100% (0/0)100% (0/0)100% (0/0)
     
class PartialDefinitionCombiner$DefinitionComparator100% (1/1)100% (3/3)76%  (50/66)80%  (16/20)
compare (Definition, Definition): int 100% (1/1)73%  (44/60)79%  (15/19)
PartialDefinitionCombiner$DefinitionComparator (): void 100% (1/1)100% (3/3)100% (1/1)
PartialDefinitionCombiner$DefinitionComparator (PartialDefinitionCombiner$1):... 100% (1/1)100% (3/3)100% (1/1)

1/*
2 * Copyright 2007 brunella ltd
3 *
4 * Licensed under the LGPL Version 3 (the "License");
5 * you may not use this file except in compliance with the License.
6 *
7 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
8 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
11 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
12 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
13 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
14 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
15 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
16 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
17 * THE POSSIBILITY OF SUCH DAMAGE.
18 */
19package sf.qof.parser;
20 
21import java.util.ArrayList;
22import java.util.Collections;
23import java.util.Comparator;
24import java.util.List;
25 
26import sf.qof.exception.ValidationException;
27 
28/**
29 * Helper class to combine partial definitions.
30 */
31public class PartialDefinitionCombiner {
32 
33  /**
34   * Combines partial definitions.
35   * 
36   * @param definitionList  a list of <code>Definition</code> objects. May contain partial definitions
37   *                        that will be combined
38   * @return                a list of containing full definitions
39   * @throws sq.qof.exception.ValidationException if duplicate partial definitions are found
40   */
41  public static List<? extends Definition> combine(List<? extends Definition> definitionList) {
42    List<Definition> partialDefinitions = new ArrayList<Definition>();
43    List<Definition> fullDefinitions = new ArrayList<Definition>();
44    
45    for (Definition definition : definitionList) {
46      if (definition.isPartialDefinition()) {
47        partialDefinitions.add(definition);
48      } else {
49        fullDefinitions.add(definition);
50      }
51    }
52    
53    if (partialDefinitions.size() == 0) { 
54      return definitionList;
55    }
56    
57    // sort the list
58    Collections.sort(partialDefinitions, new DefinitionComparator());
59    
60    validatePartialDefinitions(partialDefinitions);
61    
62    int index = 0;
63    while (index < partialDefinitions.size()) {
64      Definition partialDefinition = partialDefinitions.get(index++);
65      if (partialDefinition.getPartialDefinitionPart() == 1) {
66        int numberOfParts = numberOfParts(partialDefinitions, index - 1);
67        if (partialDefinition instanceof ResultDefinition) {
68          ResultDefinition partialResultDefiniton = (ResultDefinition)partialDefinition;
69          ResultDefinitionImpl resultDefiniton = new ResultDefinitionImpl();
70          resultDefiniton.setType(partialResultDefiniton.getType());
71          resultDefiniton.setField(partialResultDefiniton.getField());
72          resultDefiniton.setConstructorParameter(partialResultDefiniton.getConstructorParameter());
73          resultDefiniton.setIsMapKey(partialResultDefiniton.isMapKey());
74          if (partialResultDefiniton.getColumns() != null) {
75            String[] columns = new String[numberOfParts];
76            resultDefiniton.setColumns(columns);
77            columns[0] = partialResultDefiniton.getColumns()[0];
78            for (int i = 1; i < numberOfParts; i++) {
79              columns[i] = ((ResultDefinition)partialDefinitions.get(index++)).getColumns()[0];
80            }
81          } else {
82            int[] indexes = new int[numberOfParts];
83            resultDefiniton.setIndexes(indexes);
84            indexes[0] = partialResultDefiniton.getIndexes()[0];
85            for (int i = 1; i < numberOfParts; i++) {
86              indexes[i] = ((ResultDefinition)partialDefinitions.get(index++)).getIndexes()[0];
87            }
88          }
89          fullDefinitions.add(resultDefiniton);
90        } else {
91          ParameterDefinition partialParameterDefiniton = (ParameterDefinition)partialDefinition;
92          ParameterDefinitionImpl parameterDefiniton = new ParameterDefinitionImpl();
93          parameterDefiniton.setType(partialParameterDefiniton.getType());
94          parameterDefiniton.setField(partialParameterDefiniton.getField());
95          parameterDefiniton.setNames(partialParameterDefiniton.getNames());
96          parameterDefiniton.setParameter(partialParameterDefiniton.getParameter());
97          int[] indexes = new int[numberOfParts];
98          parameterDefiniton.setIndexes(indexes);
99          indexes[0] = partialParameterDefiniton.getIndexes()[0];
100          for (int i = 1; i < numberOfParts; i++) {
101            indexes[i] = ((ParameterDefinition)partialDefinitions.get(index++)).getIndexes()[0];
102          }
103          fullDefinitions.add(parameterDefiniton);
104        }
105      }
106    }
107    
108    return fullDefinitions;
109  }
110 
111  private static int numberOfParts(List<Definition> list, int start) {
112    String type = makeEmptyIfNull(list.get(start).getType());
113    String group = makeEmptyIfNull(list.get(start).getPartialDefinitionGroup());
114    int i = 1;
115    while (i + start < list.size()) {
116      if (!type.equals(makeEmptyIfNull(list.get(start + i).getType())) || 
117          !group.equals(makeEmptyIfNull(list.get(start + i).getPartialDefinitionGroup()))) {
118        break;
119      }
120      i++;
121    }
122    return i;
123  }
124 
125  private static String makeEmptyIfNull(String string) {
126    return string == null ? "" : string;
127  }
128  
129  private static void validatePartialDefinitions(List<Definition> partialDefinitions) {
130    DefinitionComparator comparator = new DefinitionComparator();
131    Definition lastDefinition = partialDefinitions.get(0);
132    for (int i = 1; i < partialDefinitions.size(); i++) {
133      Definition currentDefinition = partialDefinitions.get(i);
134      if (comparator.compare(lastDefinition, currentDefinition) == 0 ) {
135        throw new ValidationException("Duplicate partial definition");
136      }
137      lastDefinition = currentDefinition;
138    }
139  }
140 
141  private static class DefinitionComparator implements Comparator<Definition> {
142    public int compare(Definition o1, Definition o2) {
143      int cmp;
144      String type1 = o1.getType();
145      String type2 = o2.getType();
146      if (type1 != null) {
147        cmp = type1.compareTo(type2);
148      } else if (type2 != null) {
149        cmp = -type2.compareTo(type1);
150      } else {
151        cmp = 0;
152      }
153      if (cmp != 0) {
154        return cmp;
155      }
156      String group1 = o1.getPartialDefinitionGroup();
157      String group2 = o2.getPartialDefinitionGroup();
158      if (group1 != null) {
159        cmp = group1.compareTo(group2);
160      } else if (group2 != null) {
161        cmp = -group2.compareTo(group1);
162      } else {
163        cmp = 0;
164      }
165      if (cmp != 0) {
166        return cmp;
167      }
168      return o1.getPartialDefinitionPart() - o2.getPartialDefinitionPart();
169    }
170  }
171}

[all classes][sf.qof.parser]
EMMA 2.0.5312 (C) Vladimir Roubtsov