29 import java.util.Vector; |
28 import java.util.Vector; |
30 |
29 |
31 import org.apache.tools.ant.BuildException; |
30 import org.apache.tools.ant.BuildException; |
32 import org.apache.tools.ant.Project; |
31 import org.apache.tools.ant.Project; |
33 import org.apache.tools.ant.Target; |
32 import org.apache.tools.ant.Target; |
|
33 import org.apache.tools.ant.types.DataType; |
34 import org.dom4j.Comment; |
34 import org.dom4j.Comment; |
35 import org.dom4j.Document; |
35 import org.dom4j.Document; |
|
36 import org.dom4j.DocumentException; |
36 import org.dom4j.Element; |
37 import org.dom4j.Element; |
37 import org.dom4j.Node; |
38 import org.dom4j.Node; |
38 import org.dom4j.Visitor; |
39 import org.dom4j.Visitor; |
39 import org.dom4j.VisitorSupport; |
40 import org.dom4j.VisitorSupport; |
40 import org.dom4j.io.SAXReader; |
41 import org.dom4j.io.SAXReader; |
41 import org.dom4j.DocumentException; |
42 |
42 |
43 import com.nokia.helium.ant.data.PropertyCommentMeta; |
43 import com.nokia.helium.core.ant.types.HlmPostDefImpl; |
|
44 |
|
45 import com.nokia.helium.ant.data.PropertyMeta; |
44 import com.nokia.helium.ant.data.PropertyMeta; |
46 |
45 import com.nokia.helium.core.ant.PostBuildAction; |
47 |
46 |
48 /** |
47 /** |
49 * Class to store the status of the signal of a particular target. |
48 * Class to store the status of the signal of a particular target. |
50 */ |
49 */ |
51 public class BuildStatusDef extends HlmPostDefImpl |
50 public class BuildStatusDef extends DataType implements PostBuildAction { |
52 { |
51 private static final String DEPRECATED = "deprecated:"; |
53 private HashSet<String> output = new HashSet<String>(); |
52 private HashSet<String> output = new HashSet<String>(); |
54 |
53 |
55 |
54 @Override |
56 public void execute(Project prj, String module, String[] targetNames) |
55 public void executeOnPostBuild(Project project, String[] targetNames) { |
57 { |
56 // Run after targets execute so dynamic target names are resolved |
58 //Run after targets execute so dynamic target names are resolved |
57 for (int i = 0; i < targetNames.length; i++) { |
59 for (int i = 0; i < targetNames.length; i++) |
|
60 { |
|
61 String[] array = { targetNames[i] }; |
58 String[] array = { targetNames[i] }; |
62 Target target = findTarget(targetNames[i], getProject(), array); |
59 Target target = findTarget(targetNames[i], getProject(), array); |
63 targetCallsHeliumTarget(target, getProject()); |
60 targetCallsHeliumTarget(target, getProject()); |
64 } |
61 } |
65 checkTargetsProperties(getProject()); |
62 checkTargetsProperties(getProject()); |
66 |
63 checkDeprecatedProperties(getProject()); |
67 if (!output.isEmpty()) |
64 |
68 { |
65 if (!output.isEmpty()) { |
69 log("*** Configuration report ***", Project.MSG_INFO); |
66 log("*** Configuration report ***", Project.MSG_INFO); |
70 for (String outputStr : output) |
67 for (String outputStr : output) { |
71 log(outputStr, Project.MSG_INFO); |
68 log(outputStr, Project.MSG_INFO); |
72 } |
69 } |
73 } |
70 } |
74 |
71 } |
75 /** |
72 |
|
73 /** |
76 * @param desiredTarget |
74 * @param desiredTarget |
77 * Target name to search |
75 * Target name to search |
78 * @param project |
76 * @param project |
79 * Object of the project |
77 * Object of the project |
80 * @param targetNames |
78 * @param targetNames |
81 * Array of target names |
79 * Array of target names |
82 * |
80 * |
83 */ |
81 */ |
84 @SuppressWarnings("unchecked") |
82 @SuppressWarnings("unchecked") |
85 public Target findTarget(String desiredTarget, Project project, String[] targetNames) |
83 public Target findTarget(String desiredTarget, Project project, |
86 { |
84 String[] targetNames) { |
87 Hashtable<String, Target> targets; |
85 Hashtable<String, Target> targets; |
88 Vector<Target> sorted; |
86 Vector<Target> sorted; |
89 |
87 |
90 // get all targets of the current project |
88 // get all targets of the current project |
91 targets = project.getTargets(); |
89 targets = project.getTargets(); |
92 |
90 |
93 // sort all targets of the current project |
91 // sort all targets of the current project |
94 sorted = project.topoSort(targetNames[0], targets); |
92 sorted = project.topoSort(targetNames[0], targets); |
95 |
93 |
96 // Find the desiredTarget Target object |
94 // Find the desiredTarget Target object |
97 for (Target target : sorted) |
95 for (Target target : sorted) { |
98 { |
96 if (target.getName().equals(desiredTarget)) { |
99 if (target.getName().equals(desiredTarget)) |
|
100 { |
|
101 return target; |
97 return target; |
102 } |
98 } |
103 } |
99 } |
104 throw new BuildException("Could not find target matching " + desiredTarget + "\n"); |
100 throw new BuildException("Could not find target matching " |
105 } |
101 + desiredTarget + "\n"); |
106 |
102 } |
107 /** |
103 |
108 * If a target defined outside helium are calling a private Helium target then print warning |
104 /** |
|
105 * If a target defined outside helium are calling a private Helium target |
|
106 * then print warning |
109 * |
107 * |
110 */ |
108 */ |
111 @SuppressWarnings("unchecked") |
109 @SuppressWarnings("unchecked") |
112 public void targetCallsHeliumTarget(Target target, Project project) |
110 public void targetCallsHeliumTarget(Target target, Project project) { |
113 { |
|
114 String location = target.getLocation().getFileName(); |
111 String location = target.getLocation().getFileName(); |
115 |
112 |
116 try { |
113 try { |
117 String heliumpath = new File(project.getProperty("helium.dir")).getCanonicalPath(); |
114 String heliumpath = new File(project.getProperty("helium.dir")) |
|
115 .getCanonicalPath(); |
118 String targetpath = new File(location).getCanonicalPath(); |
116 String targetpath = new File(location).getCanonicalPath(); |
119 |
117 |
120 if (!targetpath.contains(heliumpath)) |
118 if (!targetpath.contains(heliumpath)) { |
121 { |
|
122 ArrayList<String> antcallTargets = new ArrayList<String>(); |
119 ArrayList<String> antcallTargets = new ArrayList<String>(); |
123 Visitor visitorTarget = new AntTargetVisitor(antcallTargets, project); |
120 Visitor visitorTarget = new AntTargetVisitor(antcallTargets, |
124 |
121 project); |
|
122 |
125 Element element = findTargetElement(target, project); |
123 Element element = findTargetElement(target, project); |
126 if (element != null) |
124 if (element != null) { |
127 element.accept(visitorTarget); |
125 element.accept(visitorTarget); |
128 for (String depTargetString : antcallTargets) |
126 } |
129 { |
127 for (String depTargetString : antcallTargets) { |
130 String[] array = { depTargetString }; |
128 String[] array = { depTargetString }; |
131 try { |
129 try { |
132 Target depTarget = findTarget(depTargetString, project, array); |
130 Target depTarget = findTarget(depTargetString, project, |
133 targetCallsHeliumTarget(depTarget, project); |
131 array); |
134 } catch (BuildException x) { |
132 targetCallsHeliumTarget(depTarget, project); |
135 // We are Ignoring the errors as no need to fail the build. |
133 } catch (BuildException x) { |
136 log("Exception occured while target defined outside helium are calling a private Helium target " + x.toString(), Project.MSG_DEBUG); |
134 // We are Ignoring the errors as no need to fail the |
|
135 // build. |
|
136 log( |
|
137 "Exception occured while target defined outside helium are calling a private Helium target " |
|
138 + x.toString(), Project.MSG_DEBUG); |
137 x = null; |
139 x = null; |
138 } |
140 } |
139 } |
141 } |
140 |
142 |
141 |
143 for (Enumeration<String> depsEnum = target.getDependencies(); depsEnum |
142 for (Enumeration<String> depsEnum = target.getDependencies(); depsEnum.hasMoreElements();) |
144 .hasMoreElements();) { |
143 { |
|
144 String depTargetString = depsEnum.nextElement(); |
145 String depTargetString = depsEnum.nextElement(); |
145 String[] array = { depTargetString }; |
146 String[] array = { depTargetString }; |
146 try { |
147 try { |
147 Target depTarget = findTarget(depTargetString, project, array); |
148 Target depTarget = findTarget(depTargetString, project, |
148 targetCallsHeliumTarget(depTarget, project); |
149 array); |
|
150 targetCallsHeliumTarget(depTarget, project); |
149 } catch (BuildException x) { |
151 } catch (BuildException x) { |
150 //We are Ignoring the errors as no need to fail the build. |
152 // We are Ignoring the errors as no need to fail the |
151 log("Exception occured while target defined outside helium are calling a private Helium target " + x.toString(), Project.MSG_DEBUG); |
153 // build. |
|
154 log( |
|
155 "Exception occured while target defined outside helium are calling a private Helium target " |
|
156 + x.toString(), Project.MSG_DEBUG); |
152 x = null; |
157 x = null; |
153 } |
158 } |
154 } |
159 } |
155 } |
160 } else { |
156 else |
|
157 { |
|
158 checkIfTargetPrivate(target, project); |
161 checkIfTargetPrivate(target, project); |
159 } |
162 } |
160 |
163 |
161 } catch (IOException e) { |
164 } catch (IOException e) { |
162 //We are Ignoring the errors as no need to fail the build. |
165 // We are Ignoring the errors as no need to fail the build. |
163 log("IOException occured while target defined outside helium are calling a private Helium target " + e.getMessage(), Project.MSG_DEBUG); |
166 log( |
|
167 "IOException occured while target defined outside helium are calling a private Helium target " |
|
168 + e.getMessage(), Project.MSG_DEBUG); |
164 e.printStackTrace(); |
169 e.printStackTrace(); |
165 } |
170 } |
166 } |
171 } |
167 |
172 |
168 private class AntTargetVisitor extends VisitorSupport |
173 private class AntTargetVisitor extends VisitorSupport { |
169 { |
|
170 private List<String> targetList; |
174 private List<String> targetList; |
171 private Project project; |
175 private Project project; |
172 |
176 |
173 public AntTargetVisitor(List<String> targetList, Project project) |
177 public AntTargetVisitor(List<String> targetList, Project project) { |
174 { |
|
175 this.targetList = targetList; |
178 this.targetList = targetList; |
176 this.project = project; |
179 this.project = project; |
177 } |
180 } |
178 |
181 |
179 public void visit(Element node) |
182 public void visit(Element node) { |
180 { |
|
181 String name = node.getName(); |
183 String name = node.getName(); |
182 if (name.equals("antcall") || name.equals("runtarget")) |
184 if (name.equals("antcall") || name.equals("runtarget")) { |
183 { |
|
184 String text = node.attributeValue("target"); |
185 String text = node.attributeValue("target"); |
185 extractTarget(text); |
186 extractTarget(text); |
186 } |
187 } |
187 } |
188 } |
188 |
189 |
189 private void extractTarget(String text) |
190 private void extractTarget(String text) { |
190 { |
|
191 String iText = project.replaceProperties(text); |
191 String iText = project.replaceProperties(text); |
192 targetList.add(iText); |
192 targetList.add(iText); |
193 } |
193 } |
194 |
194 |
195 } |
195 } |
196 |
196 |
197 /** |
197 /** |
198 * Find the xml Element for the target |
198 * Find the xml Element for the target |
199 * |
199 * |
200 */ |
200 */ |
201 @SuppressWarnings("unchecked") |
201 @SuppressWarnings("unchecked") |
202 public Element findTargetElement(Target target, Project project) |
202 public Element findTargetElement(Target target, Project project) { |
203 { |
|
204 SAXReader xmlReader = new SAXReader(); |
203 SAXReader xmlReader = new SAXReader(); |
205 |
204 |
206 Document antDoc = null; |
205 Document antDoc = null; |
207 |
206 |
208 String location = target.getLocation().getFileName(); |
207 String location = target.getLocation().getFileName(); |
209 |
208 |
210 try { |
209 try { |
211 File file = new File(location); |
210 File file = new File(location); |
212 antDoc = xmlReader.read(file); |
211 antDoc = xmlReader.read(file); |
213 } catch (DocumentException e) { |
212 } catch (DocumentException e) { |
214 // We are Ignoring the errors as no need to fail the build. |
213 // We are Ignoring the errors as no need to fail the build. |
215 log("Not able read the XML file. " + e.getMessage(), Project.MSG_WARN); |
214 log("Not able read the XML file. " + e.getMessage(), |
216 } |
215 Project.MSG_WARN); |
217 |
216 } |
|
217 |
218 String projectName = antDoc.valueOf("/project/@name"); |
218 String projectName = antDoc.valueOf("/project/@name"); |
219 for (Iterator<Element> iterator = antDoc.selectNodes("//target").iterator(); iterator.hasNext();) |
219 for (Iterator<Element> iterator = antDoc.selectNodes("//target") |
220 { |
220 .iterator(); iterator.hasNext();) { |
221 Element element = iterator.next(); |
221 Element element = iterator.next(); |
222 |
222 |
223 String targetName = element.attributeValue("name"); |
223 String targetName = element.attributeValue("name"); |
224 if (targetName.equals(target.getName()) || (projectName + "." + targetName).equals(target.getName())) |
224 if (targetName.equals(target.getName()) |
|
225 || (projectName + "." + targetName) |
|
226 .equals(target.getName())) { |
225 return element; |
227 return element; |
|
228 } |
226 } |
229 } |
227 return null; |
230 return null; |
228 } |
231 } |
229 |
232 |
230 /** |
233 /** |
231 * If target has comment that says it is private them print warning |
234 * If target has comment that says it is private them print warning |
232 * |
235 * |
233 */ |
236 */ |
234 @SuppressWarnings("unchecked") |
237 @SuppressWarnings("unchecked") |
235 public void checkIfTargetPrivate(Target target, Project project) |
238 public void checkIfTargetPrivate(Target target, Project project) { |
236 { |
|
237 Element targetElement = findTargetElement(target, project); |
239 Element targetElement = findTargetElement(target, project); |
238 if (targetElement != null) |
240 if (targetElement != null) { |
239 { |
241 List<Node> children = targetElement |
240 List<Node> children = targetElement.selectNodes("preceding-sibling::node()"); |
242 .selectNodes("preceding-sibling::node()"); |
241 if (children.size() > 0) |
243 if (children.size() > 0) { |
242 { |
|
243 // Scan past the text nodes, which are most likely whitespace |
244 // Scan past the text nodes, which are most likely whitespace |
244 int index = children.size() - 1; |
245 int index = children.size() - 1; |
245 Node child = children.get(index); |
246 Node child = children.get(index); |
246 while (index > 0 && child.getNodeType() == Node.TEXT_NODE) |
247 while (index > 0 && child.getNodeType() == Node.TEXT_NODE) { |
247 { |
|
248 index--; |
248 index--; |
249 child = (Node) children.get(index); |
249 child = (Node) children.get(index); |
250 } |
250 } |
251 |
251 |
252 // Check if there is a comment node |
252 // Check if there is a comment node |
253 String commentText = null; |
253 String commentText = null; |
254 if (child.getNodeType() == Node.COMMENT_NODE) |
254 if (child.getNodeType() == Node.COMMENT_NODE) { |
255 { |
|
256 Comment macroComment = (Comment) child; |
255 Comment macroComment = (Comment) child; |
257 commentText = macroComment.getStringValue().trim(); |
256 commentText = macroComment.getStringValue().trim(); |
258 //log(macroName + " comment: " + commentText, Project.MSG_DEBUG); |
257 // log(macroName + " comment: " + commentText, |
259 } |
258 // Project.MSG_DEBUG); |
260 |
259 } |
261 if (commentText != null) |
260 |
|
261 if (commentText != null) { |
|
262 if (commentText.contains("Private:")) { |
|
263 output |
|
264 .add("Warning: " |
|
265 + target.getName() |
|
266 + " is private and should only be called by helium"); |
|
267 } |
|
268 if (commentText.contains("<deprecated>")) { |
|
269 output.add("Warning: " + target.getName() + "\n" |
|
270 + commentText); |
|
271 } |
|
272 } |
|
273 } |
|
274 } |
|
275 } |
|
276 |
|
277 /** |
|
278 * To check, is the private properties are overridden by customers. |
|
279 * |
|
280 * @param project |
|
281 */ |
|
282 public void checkTargetsProperties(Project project) { |
|
283 try { |
|
284 String heliumpath = new File(project.getProperty("helium.dir")) |
|
285 .getCanonicalPath(); |
|
286 com.nokia.helium.ant.data.Database db = new com.nokia.helium.ant.data.Database( |
|
287 project, "private"); |
|
288 ArrayList<String> customerProps = getCustomerProperties(project); |
|
289 |
|
290 for (PropertyMeta propertyMeta : db.getProperties()) { |
|
291 if (propertyMeta.getType().equals("boolean")) |
262 { |
292 { |
263 if (commentText.contains("Private:")) |
293 String value = project.getProperty(propertyMeta.getName()); |
|
294 if (value != null && !value.equals("true") && !value.equals("false")) |
264 { |
295 { |
265 output.add("Warning: " + target.getName() + " is private and should only be called by helium"); |
296 output.add("Warning: " + propertyMeta.getName() + " property is boolean type and not set to true or false, value is " + value); |
266 } |
297 } |
267 if (commentText.contains("<deprecated>")) |
298 } |
|
299 } |
|
300 for (PropertyCommentMeta propertyMeta : db.getCommentProperties()) { |
|
301 if (propertyMeta.getType().equals("boolean")) |
|
302 { |
|
303 String value = project.getProperty(propertyMeta.getName()); |
|
304 if (value != null && !value.equals("true") && !value.equals("false")) |
268 { |
305 { |
269 output.add("Warning: " + target.getName() + "\n" + commentText); |
306 output.add("Warning: " + propertyMeta.getName() + " property is boolean type and not set to true or false, value is " + value); |
270 } |
307 } |
271 } |
308 } |
272 } |
309 } |
273 } |
310 for (PropertyMeta propertyMeta : db.getProperties()) { |
274 } |
311 if (propertyMeta.getLocation().contains(heliumpath) |
275 |
312 && propertyMeta.getScope().equals("private") |
|
313 && customerProps.contains(propertyMeta.getName())) { |
|
314 output.add("Warning: " + propertyMeta.getName() |
|
315 + " property has been overridden"); |
|
316 } |
|
317 } |
|
318 |
|
319 for (PropertyCommentMeta propertyCommentMeta : db.getCommentProperties()) { |
|
320 if (propertyCommentMeta.getLocation().contains(heliumpath) |
|
321 && propertyCommentMeta.getScope().equals("private") |
|
322 && customerProps |
|
323 .contains(propertyCommentMeta.getName())) { |
|
324 output.add("Warning: " + propertyCommentMeta.getName() |
|
325 + " property has been overridden"); |
|
326 } |
|
327 } |
|
328 } catch (IOException e) { |
|
329 e.printStackTrace(); |
|
330 } |
|
331 } |
|
332 |
|
333 /** |
|
334 * To display the warnings for deprecated properties. |
|
335 * |
|
336 * @param project |
|
337 */ |
|
338 public void checkDeprecatedProperties(Project project) { |
|
339 try { |
|
340 String heliumpath = new File(project.getProperty("helium.dir")) |
|
341 .getCanonicalPath(); |
|
342 com.nokia.helium.ant.data.Database db = new com.nokia.helium.ant.data.Database( |
|
343 project, "private"); |
|
344 ArrayList<String> customerProps = getCustomerProperties(project); |
|
345 |
|
346 for (PropertyMeta propertyMeta : db.getProperties()) { |
|
347 if (propertyMeta.getLocation().contains(heliumpath) |
|
348 && (!propertyMeta.getDeprecated().equals("")) |
|
349 && customerProps.contains(propertyMeta.getName())) { |
|
350 output.add("Warning: " |
|
351 + propertyMeta.getName() |
|
352 + " property has been deprecated " |
|
353 + propertyMeta.getDeprecated() |
|
354 + "." |
|
355 + propertyMeta.getSummary().substring( |
|
356 propertyMeta.getSummary().lastIndexOf( |
|
357 DEPRECATED) |
|
358 + DEPRECATED.length())); |
|
359 } |
|
360 } |
|
361 |
|
362 for (PropertyCommentMeta propertyCommentMeta : db |
|
363 .getCommentProperties()) { |
|
364 if (propertyCommentMeta.getLocation().contains(heliumpath) |
|
365 && (!propertyCommentMeta.getDeprecated().equals("")) |
|
366 && customerProps |
|
367 .contains(propertyCommentMeta.getName())) { |
|
368 output.add("Warning: " |
|
369 + propertyCommentMeta.getName() |
|
370 + " property has been deprecated " |
|
371 + propertyCommentMeta.getDeprecated() |
|
372 + "." |
|
373 + propertyCommentMeta.getSummary().substring( |
|
374 propertyCommentMeta.getSummary() |
|
375 .lastIndexOf(DEPRECATED) |
|
376 + DEPRECATED.length())); |
|
377 } |
|
378 } |
|
379 } catch (IOException e) { |
|
380 e.printStackTrace(); |
|
381 } |
|
382 } |
|
383 |
276 @SuppressWarnings("unchecked") |
384 @SuppressWarnings("unchecked") |
277 public void checkTargetsProperties(Project project) |
385 public ArrayList<String> getCustomerProperties(Project project) { |
278 { |
|
279 try { |
|
280 String heliumpath = new File(project.getProperty("helium.dir")).getCanonicalPath(); |
|
281 com.nokia.helium.ant.data.Database db = new com.nokia.helium.ant.data.Database(project, "private"); |
|
282 ArrayList<String> customerProps = getCustomerProperties(project); |
|
283 |
|
284 for (PropertyMeta propertyMeta : db.getProperties()) |
|
285 { |
|
286 if (propertyMeta.getLocation().contains(heliumpath) && propertyMeta.getScope().equals("private") && customerProps.contains(propertyMeta.getName())) |
|
287 { |
|
288 output.add("Warning: " + propertyMeta.getName() + " property has been overridden"); |
|
289 } |
|
290 } |
|
291 } catch (IOException e) { e.printStackTrace(); } |
|
292 } |
|
293 |
|
294 @SuppressWarnings("unchecked") |
|
295 public ArrayList<String> getCustomerProperties(Project project) |
|
296 { |
|
297 ArrayList<String> props = new ArrayList<String>(); |
386 ArrayList<String> props = new ArrayList<String>(); |
298 Database db = new Database(null, null, null); |
387 Database db = new Database(null, null, null); |
299 try { |
388 try { |
300 String heliumpath = new File(project.getProperty("helium.dir")).getCanonicalPath(); |
389 String heliumpath = new File(project.getProperty("helium.dir")) |
301 |
390 .getCanonicalPath(); |
302 for (Object object : db.getAntFiles(project)) |
391 |
303 { |
392 for (Object object : db.getAntFiles(project)) { |
304 String antFile = (String)object; |
393 String antFile = (String) object; |
305 antFile = new File(antFile).getCanonicalPath(); |
394 antFile = new File(antFile).getCanonicalPath(); |
306 |
395 |
307 if (!antFile.contains(heliumpath)) |
396 if (!antFile.contains(heliumpath)) { |
308 { |
|
309 SAXReader xmlReader = new SAXReader(); |
397 SAXReader xmlReader = new SAXReader(); |
310 Document antDoc = xmlReader.read(new File(antFile)); |
398 Document antDoc = xmlReader.read(new File(antFile)); |
311 |
399 |
312 List<Element> propertyNodes = antDoc.selectNodes("//property | //param"); |
400 List<Element> propertyNodes = antDoc |
313 for (Element propertyNode : propertyNodes) |
401 .selectNodes("//property | //param"); |
314 { |
402 for (Element propertyNode : propertyNodes) { |
315 props.add(propertyNode.attributeValue("name")); |
403 props.add(propertyNode.attributeValue("name")); |
316 } |
404 } |
317 } |
405 } |
318 } |
406 } |
319 } catch (IOException e) { |
407 } catch (IOException e) { |
320 // We are Ignoring the errors as no need to fail the build. |
408 // We are Ignoring the errors as no need to fail the build. |
321 log("IOException: Not able read the Customer Properties " + e.getMessage(), Project.MSG_WARN); |
409 log("IOException: Not able read the Customer Properties " |
|
410 + e.getMessage(), Project.MSG_WARN); |
322 } catch (DocumentException e) { |
411 } catch (DocumentException e) { |
323 // We are Ignoring the errors as no need to fail the build. |
412 // We are Ignoring the errors as no need to fail the build. |
324 log("DocumentException: Not able read the Customer Properties " + e.getMessage(), Project.MSG_WARN); |
413 log("DocumentException: Not able read the Customer Properties " |
325 } |
414 + e.getMessage(), Project.MSG_WARN); |
326 |
415 } |
|
416 |
327 return props; |
417 return props; |
328 } |
418 } |
329 |
419 |
330 } |
420 } |