View Javadoc
1   /*
2    * FIEBDC 3 parser  
3    * Copyright (C) 2014 DiSiD Technologies
4    *
5    * This program is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with this program.  If not, see <http://www.gnu.org/copyleft/gpl.html>.
17   */
18  
19  package com.disid.fiebdc3;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  /**
25   * Breakdown information a Fiebdc 3 database concept. A concept of chapter type
26   * might be composed of other subchapters or concepts of type work unit. This
27   * class models the information of each subconcept in the breakdown of the
28   * parent concept.
29   * 
30   * @author DiSiD Team
31   */
32  public class ConceptBreakdown {
33  
34      private String parentConceptCode;
35  
36      private String conceptCode;
37  
38      private Float factor = 1.0f;
39  
40      private Float performance = 1.0f;
41  
42      private List<ConceptBreakdown> childBreakdown;
43  
44      private Measurement measurement;
45  
46      /**
47       * Creates a root or orphan breakdown information entry for a concept.
48       * 
49       * @param conceptCode
50       *            which uniquely identifies the subchapter's code
51       */
52      ConceptBreakdown(String conceptCode) {
53          this.parentConceptCode = null;
54          this.conceptCode = cleanCode(conceptCode);
55      }
56  
57      /**
58       * Creates a breakdown information entry for a concept.
59       * 
60       * @param parentConceptCode
61       *            which uniquely identifies a parent chapter's code
62       * @param conceptCode
63       *            which uniquely identifies the subchapter's code
64       */
65      ConceptBreakdown(String parentConceptCode, String conceptCode) {
66          this.parentConceptCode = cleanCode(parentConceptCode);
67          this.conceptCode = cleanCode(conceptCode);
68      }
69  
70      /**
71       * Spec definition:<br/>
72       * <i>CODIGO_HIJO: CODIGO de cada concepto que interviene en la
73       * descomposición</i>
74       */
75      public String getConceptCode() {
76          return conceptCode;
77      }
78  
79      public void setConceptCode(String code) {
80          this.conceptCode = cleanCode(code);
81      }
82  
83      /**
84       * Spec definition:<br/>
85       * <i>CODIGO_PADRE: CODIGO del concepto descompuesto</i>
86       */
87      public String getParentConceptCode() {
88          return parentConceptCode;
89      }
90  
91      public void setParentConceptCode(String parentConceptCode) {
92          this.parentConceptCode = parentConceptCode;
93      }
94  
95      /**
96       * Spec definition:<br/>
97       * <i>FACTOR: Factor de rendimiento, por defecto 1.0</i>
98       */
99      public Float getFactor() {
100         return factor;
101     }
102 
103     public void setFactor(Float factor) {
104         this.factor = factor;
105     }
106 
107     /**
108      * Spec definition:<br/>
109      * <i>RENDIMIENTO: Número de unidades, rendimiento o medición, por defecto
110      * 1.0</i>
111      */
112     public Float getPerformance() {
113         return performance;
114     }
115 
116     public void setPerformance(Float performance) {
117         this.performance = performance;
118     }
119 
120     protected boolean isMyConceptCode(String code) {
121         String cleanedCode = cleanCode(code);
122 
123         return (this.conceptCode != null && this.conceptCode
124                 .equals(cleanedCode));
125     }
126 
127     private String cleanCode(String code) {
128         if (code == null) {
129             return null;
130         }
131         while (code.endsWith("#")) {
132             code = code.substring(0, code.length() - 1);
133         }
134         return code;
135     }
136 
137     /**
138      * Breakdown of this chapter in subchapters or work units.
139      * 
140      * @return the list of child BreakdownInfos.
141      */
142     public Iterable<ConceptBreakdown> getChildBreakdownInfos() {
143         return childBreakdown;
144     }
145 
146     /**
147      * Adds a new child BreakdownInfo concept
148      * 
149      * @param breakdownInfo
150      *            the child breakdownInfo
151      * @return if it was already included as a breakdownInfo
152      */
153     boolean addChildBreakdownInfo(ConceptBreakdown breakdownInfo) {
154         if (childBreakdown == null) {
155             childBreakdown = new ArrayList<ConceptBreakdown>();
156         }
157         return childBreakdown.add(breakdownInfo);
158     }
159 
160     /**
161      * Returns this or a child BreakdownInfo with the given code, which might
162      * include '\' separators to define a path of concept codes.
163      * 
164      * @param code
165      *            to find
166      * @return the found code's BreakdownInfo or null
167      */
168     public ConceptBreakdown getCodeBreakdown(String conceptCode) {
169         ConceptBreakdown bdinfo = isMyConceptCode(conceptCode) ? this : null;
170 
171         if (bdinfo != null) {
172             return bdinfo;
173         }
174 
175         // If its not this chapter's concept code, look in the child
176         // breakdowns
177         int pathPosition = conceptCode.indexOf('\\');
178         if (pathPosition > 0) {
179             String parentCode = conceptCode.substring(0, pathPosition);
180             String childCode = conceptCode.substring(pathPosition + 1);
181             if (isMyConceptCode(parentCode)) {
182                 return getChildBreakdown(childCode);
183             }
184         } else {
185             return getChildBreakdown(conceptCode);
186         }
187 
188         return null;
189     }
190 
191     private ConceptBreakdown getChildBreakdown(String childCode) {
192         if (childBreakdown != null) {
193             for (ConceptBreakdown childBreakdownInfo : getChildBreakdownInfos()) {
194                 ConceptBreakdown foundBreakdownInfo = childBreakdownInfo
195                         .getCodeBreakdown(childCode);
196                 if (foundBreakdownInfo != null) {
197                     return foundBreakdownInfo;
198                 }
199             }
200         }
201         return null;
202     }
203 
204     public Measurement getMeasurement() {
205         return measurement;
206     }
207 
208     public void setMeasurement(Measurement measurement) {
209         this.measurement = measurement;
210     }
211 
212     public boolean isWorkPackage() {
213         return measurement != null;
214     }
215 
216     @Override
217     public String toString() {
218         return "ConceptBreakdown {" + "Parent concept code: "
219                 + parentConceptCode
220                 + ", Concept code: " + conceptCode + ", Factor: " + factor
221                 + ", Performance: " + performance + ", Measurement: "
222                 + measurement + ", Child BreakdownInfos: \n\t" + childBreakdown
223                 + "}";
224     }
225 }