Mercurial > dive4elements > river
comparison flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java @ 1367:ab8eb2f544f2
Replaced stdout and stderr logging with log4j loggers in server classes.
flys-client/trunk@3069 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Tue, 25 Oct 2011 12:31:15 +0000 |
parents | 9bf91bce6ca4 |
children | f6fbfdc813f0 |
comparison
equal
deleted
inserted
replaced
1366:d0eb2202ffbe | 1367:ab8eb2f544f2 |
---|---|
11 import org.w3c.dom.Document; | 11 import org.w3c.dom.Document; |
12 import org.w3c.dom.Element; | 12 import org.w3c.dom.Element; |
13 import org.w3c.dom.NamedNodeMap; | 13 import org.w3c.dom.NamedNodeMap; |
14 import org.w3c.dom.Node; | 14 import org.w3c.dom.Node; |
15 import org.w3c.dom.NodeList; | 15 import org.w3c.dom.NodeList; |
16 | |
17 import org.apache.log4j.Logger; | |
16 | 18 |
17 import de.intevation.artifacts.common.ArtifactNamespaceContext; | 19 import de.intevation.artifacts.common.ArtifactNamespaceContext; |
18 import de.intevation.artifacts.common.utils.ClientProtocolUtils; | 20 import de.intevation.artifacts.common.utils.ClientProtocolUtils; |
19 import de.intevation.artifacts.common.utils.XMLUtils; | 21 import de.intevation.artifacts.common.utils.XMLUtils; |
20 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; | 22 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; |
46 /** | 48 /** |
47 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | 49 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> |
48 */ | 50 */ |
49 public class CollectionHelper { | 51 public class CollectionHelper { |
50 | 52 |
53 private static final Logger logger = | |
54 Logger.getLogger(CollectionHelper.class); | |
55 | |
56 | |
51 public static final String ERROR_ADD_ARTIFACT = "error_add_artifact"; | 57 public static final String ERROR_ADD_ARTIFACT = "error_add_artifact"; |
52 | 58 |
53 public static final String ERROR_REMOVE_ARTIFACT = "error_remove_artifact"; | 59 public static final String ERROR_REMOVE_ARTIFACT = "error_remove_artifact"; |
54 | 60 |
55 public static final String XPATH_FACETS = "art:facets/art:facet"; | 61 public static final String XPATH_FACETS = "art:facets/art:facet"; |
57 public static final String XPATH_LOADED_RECOMMENDATIONS = | 63 public static final String XPATH_LOADED_RECOMMENDATIONS = |
58 "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation"; | 64 "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation"; |
59 | 65 |
60 | 66 |
61 public static Document createAttribute(Collection collection) { | 67 public static Document createAttribute(Collection collection) { |
62 System.out.println("CollectionHelper.createAttribute"); | 68 logger.debug("CollectionHelper.createAttribute"); |
63 | 69 |
64 Document doc = XMLUtils.newDocument(); | 70 Document doc = XMLUtils.newDocument(); |
65 | 71 |
66 ElementCreator cr = new ElementCreator( | 72 ElementCreator cr = new ElementCreator( |
67 doc, | 73 doc, |
101 protected static Element createOutputElements( | 107 protected static Element createOutputElements( |
102 ElementCreator cr, | 108 ElementCreator cr, |
103 Collection c, | 109 Collection c, |
104 Map<String, OutputMode> mmodes) | 110 Map<String, OutputMode> mmodes) |
105 { | 111 { |
106 System.out.println("CollectionHelper.createOutputElements"); | 112 logger.debug("CollectionHelper.createOutputElements"); |
107 | 113 |
108 java.util.Collection<OutputMode> modes = mmodes != null | 114 java.util.Collection<OutputMode> modes = mmodes != null |
109 ? mmodes.values() | 115 ? mmodes.values() |
110 : null; | 116 : null; |
111 | 117 |
112 if (modes == null || modes.size() == 0) { | 118 if (modes == null || modes.size() == 0) { |
113 System.err.println("Collection has no modes: " + c.identifier()); | 119 logger.debug("Collection has no modes: " + c.identifier()); |
114 return null; | 120 return null; |
115 } | 121 } |
116 | 122 |
117 Element outs = cr.create("outputs"); | 123 Element outs = cr.create("outputs"); |
118 | 124 |
140 protected static Element createOutputElement( | 146 protected static Element createOutputElement( |
141 ElementCreator cr, | 147 ElementCreator cr, |
142 Collection collection, | 148 Collection collection, |
143 OutputMode mode) | 149 OutputMode mode) |
144 { | 150 { |
145 System.out.println("CollectionHelper.createOutputElement"); | 151 logger.debug("CollectionHelper.createOutputElement"); |
146 | 152 |
147 Element out = cr.create("output"); | 153 Element out = cr.create("output"); |
148 cr.addAttr(out, "name", mode.getName(), false); | 154 cr.addAttr(out, "name", mode.getName(), false); |
149 | 155 |
150 ThemeList themeList = collection.getThemeList(mode.getName()); | 156 ThemeList themeList = collection.getThemeList(mode.getName()); |
151 List<Theme> themes = themeList != null ? themeList.getThemes() : null; | 157 List<Theme> themes = themeList != null ? themeList.getThemes() : null; |
152 | 158 |
153 if (themes == null || themes.size() == 0) { | 159 if (themes == null || themes.size() == 0) { |
154 System.err.println("No themes for output mode: " + mode.getName()); | 160 logger.debug("No themes for output mode: " + mode.getName()); |
155 return null; | 161 return null; |
156 } | 162 } |
157 | 163 |
158 for (Theme theme: themes) { | 164 for (Theme theme: themes) { |
159 Element t = createThemeElement(cr, collection, theme); | 165 Element t = createThemeElement(cr, collection, theme); |
219 */ | 225 */ |
220 protected static Element createRecommendationsElements( | 226 protected static Element createRecommendationsElements( |
221 ElementCreator cr, | 227 ElementCreator cr, |
222 Collection c) | 228 Collection c) |
223 { | 229 { |
224 System.out.println("CollectionHelper.createRecommendationsElements"); | 230 logger.debug("CollectionHelper.createRecommendationsElements"); |
225 | 231 |
226 List<Recommendation> rs = c.getRecommendations(); | 232 List<Recommendation> rs = c.getRecommendations(); |
227 | 233 |
228 if (rs == null || rs.size() == 0) { | 234 if (rs == null || rs.size() == 0) { |
229 System.err.println("Collection did not load recommendations: " + | 235 logger.debug("Collection did not load recommendations: " + |
230 c.identifier()); | 236 c.identifier()); |
231 return null; | 237 return null; |
232 } | 238 } |
233 | 239 |
234 Element loaded = cr.create("loaded-recommendations"); | 240 Element loaded = cr.create("loaded-recommendations"); |
257 protected static Element createRecommendationElement( | 263 protected static Element createRecommendationElement( |
258 ElementCreator cr, | 264 ElementCreator cr, |
259 Collection c, | 265 Collection c, |
260 Recommendation r) | 266 Recommendation r) |
261 { | 267 { |
262 System.out.println("CollectionHelper.createRecommendationElement"); | 268 logger.debug("CollectionHelper.createRecommendationElement"); |
263 | 269 |
264 Element recommendation = cr.create("recommendation"); | 270 Element recommendation = cr.create("recommendation"); |
265 cr.addAttr(recommendation, "factory", r.getFactory(), true); | 271 cr.addAttr(recommendation, "factory", r.getFactory(), true); |
266 cr.addAttr(recommendation, "ids", r.getIDs(), true); | 272 cr.addAttr(recommendation, "ids", r.getIDs(), true); |
267 | 273 |
278 * operation. | 284 * operation. |
279 * | 285 * |
280 * @return a Collection with CollectionItems. | 286 * @return a Collection with CollectionItems. |
281 */ | 287 */ |
282 public static Collection parseCollection(Document description) { | 288 public static Collection parseCollection(Document description) { |
283 System.out.println("AddArtifactServiceImpl.parseCollection"); | 289 logger.debug("AddArtifactServiceImpl.parseCollection"); |
284 | 290 |
285 if (description == null) { | 291 if (description == null) { |
286 System.err.println("The DESCRIBE of the Collection is null!"); | 292 logger.warn("The DESCRIBE of the Collection is null!"); |
287 return null; | 293 return null; |
288 } | 294 } |
289 | 295 |
290 String uuid = XMLUtils.xpathString( | 296 String uuid = XMLUtils.xpathString( |
291 description, | 297 description, |
301 description, | 307 description, |
302 "art:artifact-collection/@art:name", | 308 "art:artifact-collection/@art:name", |
303 ArtifactNamespaceContext.INSTANCE); | 309 ArtifactNamespaceContext.INSTANCE); |
304 | 310 |
305 if (uuid.length() == 0) { | 311 if (uuid.length() == 0) { |
306 System.err.println("Found an invalid (zero length uuid) Collection!"); | 312 logger.warn("Found an invalid (zero length uuid) Collection!"); |
307 return null; | 313 return null; |
308 } | 314 } |
309 | 315 |
310 if (ttlStr.length() == 0) { | 316 if (ttlStr.length() == 0) { |
311 System.err.println("Found an invalid Collectioni (zero length ttl)!"); | 317 logger.warn("Found an invalid Collectioni (zero length ttl)!"); |
312 return null; | 318 return null; |
313 } | 319 } |
314 | 320 |
315 | 321 |
316 long ttl = -1; | 322 long ttl = -1; |
335 "art:artifact-collection/art:artifacts/art:artifact", | 341 "art:artifact-collection/art:artifacts/art:artifact", |
336 XPathConstants.NODESET, | 342 XPathConstants.NODESET, |
337 ArtifactNamespaceContext.INSTANCE); | 343 ArtifactNamespaceContext.INSTANCE); |
338 | 344 |
339 if (items == null || items.getLength() == 0) { | 345 if (items == null || items.getLength() == 0) { |
340 System.out.println("No collection item found for this collection."); | 346 logger.debug("No collection item found for this collection."); |
341 | 347 |
342 return c; | 348 return c; |
343 } | 349 } |
344 | 350 |
345 int size = items.getLength(); | 351 int size = items.getLength(); |
352 if (item != null) { | 358 if (item != null) { |
353 c.addItem(item); | 359 c.addItem(item); |
354 } | 360 } |
355 } | 361 } |
356 | 362 |
357 System.out.println( | 363 logger.debug( |
358 "Found " + c.getItemLength() + " collection items " + | 364 "Found " + c.getItemLength() + " collection items " + |
359 "for the Collection '" + c.identifier() + "'."); | 365 "for the Collection '" + c.identifier() + "'."); |
360 | 366 |
361 return c; | 367 return c; |
362 } | 368 } |
363 | 369 |
364 | 370 |
365 protected static Map<String, ThemeList> parseThemeLists(Document desc) { | 371 protected static Map<String, ThemeList> parseThemeLists(Document desc) { |
366 System.out.println("DescribeCollectionServiceImpl.parseThemeLists"); | 372 logger.debug("DescribeCollectionServiceImpl.parseThemeLists"); |
367 | 373 |
368 NodeList lists = (NodeList) XMLUtils.xpath( | 374 NodeList lists = (NodeList) XMLUtils.xpath( |
369 desc, | 375 desc, |
370 "/art:artifact-collection/art:attribute/art:outputs/art:output", | 376 "/art:artifact-collection/art:attribute/art:outputs/art:output", |
371 XPathConstants.NODESET, | 377 XPathConstants.NODESET, |
393 return themeList; | 399 return themeList; |
394 } | 400 } |
395 | 401 |
396 | 402 |
397 protected static ThemeList parseThemeList(Element node) { | 403 protected static ThemeList parseThemeList(Element node) { |
398 System.out.println("DescribeCollectionServiceImpl.parseThemeList"); | 404 logger.debug("DescribeCollectionServiceImpl.parseThemeList"); |
399 | 405 |
400 NodeList themes = node.getElementsByTagNameNS( | 406 NodeList themes = node.getElementsByTagNameNS( |
401 ArtifactNamespaceContext.NAMESPACE_URI, | 407 ArtifactNamespaceContext.NAMESPACE_URI, |
402 "facet"); | 408 "facet"); |
403 | 409 |
416 return new ThemeList(themeList); | 422 return new ThemeList(themeList); |
417 } | 423 } |
418 | 424 |
419 | 425 |
420 protected static Theme parseTheme(Element ele) { | 426 protected static Theme parseTheme(Element ele) { |
421 System.out.println("DescribeCollectionServiceImpl.parseTheme"); | 427 logger.debug("DescribeCollectionServiceImpl.parseTheme"); |
422 | 428 |
423 String uri = ArtifactNamespaceContext.NAMESPACE_URI; | 429 String uri = ArtifactNamespaceContext.NAMESPACE_URI; |
424 | 430 |
425 NamedNodeMap attrMap = ele.getAttributes(); | 431 NamedNodeMap attrMap = ele.getAttributes(); |
426 int attrNum = attrMap != null ? attrMap.getLength() : 0; | 432 int attrNum = attrMap != null ? attrMap.getLength() : 0; |
451 */ | 457 */ |
452 protected static CollectionItem parseCollectionItem( | 458 protected static CollectionItem parseCollectionItem( |
453 Element node, | 459 Element node, |
454 boolean outs | 460 boolean outs |
455 ) { | 461 ) { |
456 System.out.println("AddArtifactServiceImpl.parseCollectionItem"); | 462 logger.debug("AddArtifactServiceImpl.parseCollectionItem"); |
457 | 463 |
458 if (node == null) { | 464 if (node == null) { |
459 System.err.println("The node for parsing CollectionItem is null!"); | 465 logger.debug("The node for parsing CollectionItem is null!"); |
460 return null; | 466 return null; |
461 } | 467 } |
462 | 468 |
463 String uri = ArtifactNamespaceContext.NAMESPACE_URI; | 469 String uri = ArtifactNamespaceContext.NAMESPACE_URI; |
464 | 470 |
465 String uuid = node.getAttributeNS(uri, "uuid"); | 471 String uuid = node.getAttributeNS(uri, "uuid"); |
466 String hash = node.getAttributeNS(uri, "hash"); | 472 String hash = node.getAttributeNS(uri, "hash"); |
467 | 473 |
468 if (uuid == null || uuid.length() == 0) { | 474 if (uuid == null || uuid.length() == 0) { |
469 System.err.println("Found an invalid CollectionItem!"); | 475 logger.warn("Found an invalid CollectionItem!"); |
470 return null; | 476 return null; |
471 } | 477 } |
472 | 478 |
473 List<OutputMode> modes = new ArrayList<OutputMode>(); | 479 List<OutputMode> modes = new ArrayList<OutputMode>(); |
474 | 480 |
496 * @param node The root node of the outputmodes list. | 502 * @param node The root node of the outputmodes list. |
497 * | 503 * |
498 * @return a list of OutputModes. | 504 * @return a list of OutputModes. |
499 */ | 505 */ |
500 protected static List<OutputMode> parseOutputModes(Element node) { | 506 protected static List<OutputMode> parseOutputModes(Element node) { |
501 System.out.println("AddArtifactServiceImpl.parseOutputModes"); | 507 logger.debug("AddArtifactServiceImpl.parseOutputModes"); |
502 | 508 |
503 if (node == null) { | 509 if (node == null) { |
504 System.err.println("The node for parsing OutputModes is null!"); | 510 logger.debug("The node for parsing OutputModes is null!"); |
505 return null; | 511 return null; |
506 } | 512 } |
507 | 513 |
508 String uri = ArtifactNamespaceContext.NAMESPACE_URI; | 514 String uri = ArtifactNamespaceContext.NAMESPACE_URI; |
509 | 515 |
510 NodeList list = node.getElementsByTagNameNS(uri, "output"); | 516 NodeList list = node.getElementsByTagNameNS(uri, "output"); |
511 | 517 |
512 int size = list.getLength(); | 518 int size = list.getLength(); |
513 | 519 |
514 if (size == 0) { | 520 if (size == 0) { |
515 System.err.println("No outputmode nodes found!"); | 521 logger.debug("No outputmode nodes found!"); |
516 return null; | 522 return null; |
517 } | 523 } |
518 | 524 |
519 List<OutputMode> modes = new ArrayList<OutputMode>(size); | 525 List<OutputMode> modes = new ArrayList<OutputMode>(size); |
520 | 526 |
525 String desc = tmp.getAttributeNS(uri, "description"); | 531 String desc = tmp.getAttributeNS(uri, "description"); |
526 String mime = tmp.getAttributeNS(uri, "mime-type"); | 532 String mime = tmp.getAttributeNS(uri, "mime-type"); |
527 String type = tmp.getAttributeNS(uri, "type"); | 533 String type = tmp.getAttributeNS(uri, "type"); |
528 | 534 |
529 if (name.length() == 0) { | 535 if (name.length() == 0) { |
530 System.err.println("Found an invalid output mode."); | 536 logger.warn("Found an invalid output mode."); |
531 continue; | 537 continue; |
532 } | 538 } |
533 | 539 |
534 OutputMode outmode = null; | 540 OutputMode outmode = null; |
535 List<Facet> fs = extractFacets(tmp); | 541 List<Facet> fs = extractFacets(tmp); |
545 } | 551 } |
546 else if (type.equals("map")){ | 552 else if (type.equals("map")){ |
547 outmode = new MapMode(name, desc, mime, fs); | 553 outmode = new MapMode(name, desc, mime, fs); |
548 } | 554 } |
549 else { | 555 else { |
550 System.err.println("Broken Output mode without type found."); | 556 logger.warn("Broken Output mode without type found."); |
551 continue; | 557 continue; |
552 } | 558 } |
553 | 559 |
554 modes.add(outmode); | 560 modes.add(outmode); |
555 } | 561 } |
557 return modes; | 563 return modes; |
558 } | 564 } |
559 | 565 |
560 | 566 |
561 protected static List<Facet> extractFacets(Element outmode) { | 567 protected static List<Facet> extractFacets(Element outmode) { |
562 System.out.println("DescribeCollectionServiceImpl - extractFacets()"); | 568 logger.debug("DescribeCollectionServiceImpl - extractFacets()"); |
563 | 569 |
564 NodeList facetList = (NodeList) XMLUtils.xpath( | 570 NodeList facetList = (NodeList) XMLUtils.xpath( |
565 outmode, | 571 outmode, |
566 XPATH_FACETS, | 572 XPATH_FACETS, |
567 XPathConstants.NODESET, | 573 XPathConstants.NODESET, |
588 return facets; | 594 return facets; |
589 } | 595 } |
590 | 596 |
591 | 597 |
592 public static List<Recommendation> parseRecommendations(Document doc) { | 598 public static List<Recommendation> parseRecommendations(Document doc) { |
593 System.out.println("DescribeCollectionServiceImpl.parseRecommendations"); | 599 logger.debug("DescribeCollectionServiceImpl.parseRecommendations"); |
594 | 600 |
595 NodeList list = (NodeList) XMLUtils.xpath( | 601 NodeList list = (NodeList) XMLUtils.xpath( |
596 doc, | 602 doc, |
597 XPATH_LOADED_RECOMMENDATIONS, | 603 XPATH_LOADED_RECOMMENDATIONS, |
598 XPathConstants.NODESET, | 604 XPathConstants.NODESET, |
629 Artifact artifact, | 635 Artifact artifact, |
630 String url, | 636 String url, |
631 String locale) | 637 String locale) |
632 throws ServerException | 638 throws ServerException |
633 { | 639 { |
634 System.out.println("Collection.addArtifact"); | 640 logger.debug("Collection.addArtifact"); |
635 | 641 |
636 if (collection == null) { | 642 if (collection == null) { |
637 System.err.println("The given Collection is null!"); | 643 logger.warn("The given Collection is null!"); |
638 return null; | 644 return null; |
639 } | 645 } |
640 | 646 |
641 Document add = ClientProtocolUtils.newAddArtifactDocument( | 647 Document add = ClientProtocolUtils.newAddArtifactDocument( |
642 artifact.getUuid(), null); | 648 artifact.getUuid(), null); |
643 | 649 |
644 HttpClient client = new HttpClientImpl(url, locale); | 650 HttpClient client = new HttpClientImpl(url, locale); |
645 | 651 |
646 try { | 652 try { |
647 System.out.println("Do HTTP request now."); | 653 logger.debug("Do HTTP request now."); |
648 | 654 |
649 Document response = (Document) client.doCollectionAction( | 655 Document response = (Document) client.doCollectionAction( |
650 add, collection.identifier(), new DocumentResponseHandler()); | 656 add, collection.identifier(), new DocumentResponseHandler()); |
651 | 657 |
652 System.out.println( | 658 logger.debug( |
653 "Finished HTTP request successfully. Parse Collection now."); | 659 "Finished HTTP request successfully. Parse Collection now."); |
654 | 660 |
655 Collection c = CollectionHelper.parseCollection(response); | 661 Collection c = CollectionHelper.parseCollection(response); |
656 | 662 |
657 if (c == null) { | 663 if (c == null) { |
659 } | 665 } |
660 | 666 |
661 return c; | 667 return c; |
662 } | 668 } |
663 catch (ConnectionException ce) { | 669 catch (ConnectionException ce) { |
664 System.err.println(ce.getLocalizedMessage()); | 670 logger.error(ce, ce); |
665 } | 671 } |
666 catch (Exception e) { | 672 catch (Exception e) { |
667 e.printStackTrace(); | 673 logger.error(e, e); |
668 } | 674 } |
669 | 675 |
670 throw new ServerException(ERROR_ADD_ARTIFACT); | 676 throw new ServerException(ERROR_ADD_ARTIFACT); |
671 } | 677 } |
672 | 678 |
681 String artifactId, | 687 String artifactId, |
682 String url, | 688 String url, |
683 String locale) | 689 String locale) |
684 throws ServerException | 690 throws ServerException |
685 { | 691 { |
686 System.out.println("Collection.removeArtifact"); | 692 logger.debug("Collection.removeArtifact"); |
687 | 693 |
688 if (collection == null) { | 694 if (collection == null) { |
689 System.err.println("The given Collection is null!"); | 695 logger.warn("The given Collection is null!"); |
690 return null; | 696 return null; |
691 } | 697 } |
692 | 698 |
693 Document remove = ClientProtocolUtils.newRemoveArtifactDocument( | 699 Document remove = ClientProtocolUtils.newRemoveArtifactDocument( |
694 artifactId); | 700 artifactId); |
695 | 701 |
696 HttpClient client = new HttpClientImpl(url, locale); | 702 HttpClient client = new HttpClientImpl(url, locale); |
697 | 703 |
698 try { | 704 try { |
699 System.out.println("Do HTTP request now."); | 705 logger.debug("Do HTTP request now."); |
700 | 706 |
701 Document response = (Document) client.doCollectionAction( | 707 Document response = (Document) client.doCollectionAction( |
702 remove, collection.identifier(), new DocumentResponseHandler()); | 708 remove, collection.identifier(), new DocumentResponseHandler()); |
703 | 709 |
704 System.out.println( | 710 logger.debug( |
705 "Finished HTTP request successfully. Parse Collection now."); | 711 "Finished HTTP request successfully. Parse Collection now."); |
706 System.out.println(XMLUtils.toString(response)); | 712 logger.debug(XMLUtils.toString(response)); |
707 | 713 |
708 Collection c = CollectionHelper.parseCollection(response); | 714 Collection c = CollectionHelper.parseCollection(response); |
709 | 715 |
710 if (c == null) { | 716 if (c == null) { |
711 throw new ServerException(ERROR_REMOVE_ARTIFACT); | 717 throw new ServerException(ERROR_REMOVE_ARTIFACT); |
712 } | 718 } |
713 | 719 |
714 return c; | 720 return c; |
715 } | 721 } |
716 catch (ConnectionException ce) { | 722 catch (ConnectionException ce) { |
717 System.err.println(ce.getLocalizedMessage()); | 723 logger.error(ce, ce); |
718 } | 724 } |
719 catch (Exception e) { | 725 catch (Exception e) { |
720 e.printStackTrace(); | 726 logger.error(e, e); |
721 } | 727 } |
722 throw new ServerException(ERROR_REMOVE_ARTIFACT); | 728 throw new ServerException(ERROR_REMOVE_ARTIFACT); |
723 } | 729 } |
724 } | 730 } |
725 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : | 731 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |