Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java @ 1055:61c051e53f9b
Moved WINFO specific stuff from FLYS into WINFO artifact.
flys-artifacts/trunk@2525 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 22 Aug 2011 15:25:48 +0000 |
parents | eccf966fb677 |
children | bd1b751deab3 |
comparison
equal
deleted
inserted
replaced
1054:1f3e944a805c | 1055:61c051e53f9b |
---|---|
1 package de.intevation.flys.artifacts; | 1 package de.intevation.flys.artifacts; |
2 | 2 |
3 import java.util.Arrays; | 3 import de.intevation.artifactdatabase.ArtifactDatabaseImpl; |
4 import java.util.ArrayList; | 4 import de.intevation.artifactdatabase.DefaultArtifact; |
5 import java.util.Collection; | 5 |
6 import java.util.Collections; | 6 import de.intevation.artifactdatabase.data.DefaultStateData; |
7 import java.util.HashMap; | 7 import de.intevation.artifactdatabase.data.StateData; |
8 import java.util.HashSet; | 8 |
9 import java.util.TreeMap; | 9 import de.intevation.artifactdatabase.state.DefaultOutput; |
10 import java.util.List; | 10 import de.intevation.artifactdatabase.state.Facet; |
11 import java.util.Map; | 11 import de.intevation.artifactdatabase.state.Output; |
12 import java.util.Set; | 12 import de.intevation.artifactdatabase.state.State; |
13 | 13 import de.intevation.artifactdatabase.state.StateEngine; |
14 import javax.xml.xpath.XPathConstants; | 14 |
15 | 15 import de.intevation.artifactdatabase.transition.TransitionEngine; |
16 import gnu.trove.TDoubleArrayList; | |
17 | |
18 import net.sf.ehcache.Cache; | |
19 | |
20 import org.apache.log4j.Logger; | |
21 | |
22 import org.w3c.dom.Document; | |
23 import org.w3c.dom.Element; | |
24 import org.w3c.dom.NodeList; | |
25 | 16 |
26 import de.intevation.artifacts.Artifact; | 17 import de.intevation.artifacts.Artifact; |
27 import de.intevation.artifacts.ArtifactDatabase; | 18 import de.intevation.artifacts.ArtifactDatabase; |
28 import de.intevation.artifacts.ArtifactDatabaseException; | 19 import de.intevation.artifacts.ArtifactDatabaseException; |
29 import de.intevation.artifacts.ArtifactFactory; | 20 import de.intevation.artifacts.ArtifactFactory; |
30 import de.intevation.artifacts.CallContext; | 21 import de.intevation.artifacts.CallContext; |
31 import de.intevation.artifacts.CallMeta; | 22 import de.intevation.artifacts.CallMeta; |
32 | 23 |
33 import de.intevation.artifacts.common.ArtifactNamespaceContext; | 24 import de.intevation.artifacts.common.ArtifactNamespaceContext; |
25 | |
34 import de.intevation.artifacts.common.utils.XMLUtils; | 26 import de.intevation.artifacts.common.utils.XMLUtils; |
35 | 27 |
36 import de.intevation.artifactdatabase.ArtifactDatabaseImpl; | 28 import de.intevation.flys.artifacts.cache.CacheFactory; |
37 import de.intevation.artifactdatabase.DefaultArtifact; | |
38 import de.intevation.artifactdatabase.data.DefaultStateData; | |
39 import de.intevation.artifactdatabase.data.StateData; | |
40 import de.intevation.artifactdatabase.state.DefaultOutput; | |
41 import de.intevation.artifactdatabase.state.Facet; | |
42 import de.intevation.artifactdatabase.state.Output; | |
43 import de.intevation.artifactdatabase.state.State; | |
44 import de.intevation.artifactdatabase.state.StateEngine; | |
45 import de.intevation.artifactdatabase.transition.TransitionEngine; | |
46 | |
47 import de.intevation.flys.utils.DoubleUtil; | |
48 | |
49 import de.intevation.flys.model.Gauge; | |
50 import de.intevation.flys.model.River; | |
51 | 29 |
52 import de.intevation.flys.artifacts.context.FLYSContext; | 30 import de.intevation.flys.artifacts.context.FLYSContext; |
53 | 31 |
54 import de.intevation.flys.artifacts.cache.CacheFactory; | 32 import de.intevation.flys.artifacts.states.DefaultState.ComputeType; |
55 | |
56 import de.intevation.flys.artifacts.model.DischargeTables; | |
57 import de.intevation.flys.artifacts.model.RiverFactory; | |
58 import de.intevation.flys.artifacts.model.Segment; | |
59 | 33 |
60 import de.intevation.flys.artifacts.states.DefaultState; | 34 import de.intevation.flys.artifacts.states.DefaultState; |
61 import de.intevation.flys.artifacts.states.DefaultState.ComputeType; | 35 |
62 import de.intevation.flys.artifacts.states.LocationDistanceSelect; | 36 import java.util.ArrayList; |
63 | 37 import java.util.Collection; |
38 import java.util.HashMap; | |
39 import java.util.HashSet; | |
40 import java.util.List; | |
41 import java.util.Map; | |
42 import java.util.Set; | |
43 import java.util.TreeMap; | |
44 | |
45 import javax.xml.xpath.XPathConstants; | |
46 | |
47 import net.sf.ehcache.Cache; | |
48 | |
49 import org.apache.log4j.Logger; | |
50 | |
51 import org.w3c.dom.Document; | |
52 import org.w3c.dom.Element; | |
53 import org.w3c.dom.NodeList; | |
64 | 54 |
65 /** | 55 /** |
66 * The defaul FLYS artifact. | 56 * The defaul FLYS artifact. |
67 * | 57 * |
68 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | 58 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> |
89 /** The constant string that shows that an operation was successful.*/ | 79 /** The constant string that shows that an operation was successful.*/ |
90 public static final String OPERATION_SUCCESSFUL = "SUCCESS"; | 80 public static final String OPERATION_SUCCESSFUL = "SUCCESS"; |
91 | 81 |
92 /** The constant string that shows that an operation failed.*/ | 82 /** The constant string that shows that an operation failed.*/ |
93 public static final String OPERATION_FAILED = "FAILURE"; | 83 public static final String OPERATION_FAILED = "FAILURE"; |
94 | |
95 /** The default number of steps between the start end end of a selected Q | |
96 * range.*/ | |
97 public static final int DEFAULT_Q_STEPS = 30; | |
98 | |
99 /** The default step width between the start end end kilometer.*/ | |
100 public static final double DEFAULT_KM_STEPS = 0.1; | |
101 | 84 |
102 | 85 |
103 /** The identifier of the current state. */ | 86 /** The identifier of the current state. */ |
104 protected String currentStateId; | 87 protected String currentStateId; |
105 | 88 |
516 if (prevs.contains(stateId)) { | 499 if (prevs.contains(stateId)) { |
517 return true; | 500 return true; |
518 } | 501 } |
519 | 502 |
520 return false; | 503 return false; |
521 } | |
522 | |
523 | |
524 /** | |
525 * Returns the selected River object based on the 'river' data that might | |
526 * have been inserted by the user. | |
527 * | |
528 * @return the selected River or null if no river has been chosen yet. | |
529 */ | |
530 public River getRiver() { | |
531 StateData dRiver = getData("river"); | |
532 | |
533 return dRiver != null | |
534 ? RiverFactory.getRiver((String) dRiver.getValue()) | |
535 : null; | |
536 } | |
537 | |
538 | |
539 /** | |
540 * Returns the selected distance of points. | |
541 * | |
542 * @return the selected distance or points. | |
543 */ | |
544 public double[] getDistance() { | |
545 StateData dMode = getData("ld_mode"); | |
546 StateData dFrom = getData("ld_from"); | |
547 StateData dTo = getData("ld_to"); | |
548 StateData dLocations = getData("ld_locations"); | |
549 | |
550 if (dMode != null) { | |
551 String mode = (String)dMode.getValue(); | |
552 if ("location".equals(mode)) { | |
553 double[] locations = getLocations(); | |
554 return new double[] { locations[0], locations[locations.length-1] }; | |
555 } | |
556 if (dFrom != null && dTo != null) { | |
557 return getDistanceByRange(dFrom, dTo); | |
558 } | |
559 } | |
560 | |
561 if (dLocations != null) { | |
562 double[] locations = getLocations(); | |
563 return new double[] { locations[0], locations[locations.length-1] }; | |
564 } | |
565 | |
566 if (dFrom != null && dTo != null) { | |
567 return getDistanceByRange(dFrom, dTo); | |
568 } | |
569 | |
570 logger.warn("No data found for distance determination!"); | |
571 | |
572 return null; | |
573 } | |
574 | |
575 | |
576 /** | |
577 * Determines the selected mode of distance/range input. | |
578 * | |
579 * @return true, if the range mode is selected otherwise false. | |
580 */ | |
581 public boolean isRange() { | |
582 StateData mode = getData("ld_mode"); | |
583 | |
584 if (mode == null) { | |
585 logger.warn("No mode location/range chosen. Defaults to range."); | |
586 return true; | |
587 } | |
588 | |
589 String value = (String) mode.getValue(); | |
590 | |
591 return value.equals("distance"); | |
592 } | |
593 | |
594 | |
595 /** | |
596 * Returns the selected locations based on a given array of locations. | |
597 * | |
598 * @param locations The StateData that contains the locations. | |
599 * | |
600 * @return the selected locations. | |
601 */ | |
602 public double[] getLocations() { | |
603 StateData dLocations = getData("ld_locations"); | |
604 String locationStr = dLocations != null | |
605 ? (String) dLocations.getValue() | |
606 : ""; | |
607 | |
608 if (locationStr == null || locationStr.length() == 0) { | |
609 logger.warn("No valid location string found!"); | |
610 return null; | |
611 } | |
612 | |
613 String[] tmp = locationStr.split(" "); | |
614 TDoubleArrayList locations = new TDoubleArrayList(); | |
615 | |
616 for (String l: tmp) { | |
617 try { | |
618 locations.add(Double.parseDouble(l)); | |
619 } | |
620 catch (NumberFormatException nfe) { | |
621 logger.warn(nfe, nfe); | |
622 } | |
623 } | |
624 | |
625 locations.sort(); | |
626 | |
627 return locations.toNativeArray(); | |
628 } | |
629 | |
630 | |
631 /** | |
632 * Returns the selected distance based on a given range (from, to). | |
633 * | |
634 * @param dFrom The StateData that contains the lower value. | |
635 * @param dTo The StateData that contains the upper value. | |
636 * | |
637 * @return the selected distance. | |
638 */ | |
639 protected double[] getDistanceByRange(StateData dFrom, StateData dTo) { | |
640 double from = Double.parseDouble((String) dFrom.getValue()); | |
641 double to = Double.parseDouble((String) dTo.getValue()); | |
642 | |
643 return new double[] { from, to }; | |
644 } | |
645 | |
646 | |
647 /** | |
648 * Returns the selected Kms. | |
649 * | |
650 * @param distance An 2dim array with [lower, upper] values. | |
651 * | |
652 * @return the selected Kms. | |
653 */ | |
654 public double[] getKms(double[] distance) { | |
655 StateData dStep = getData("ld_step"); | |
656 | |
657 if (dStep == null) { | |
658 logger.warn("No step width given. Cannot compute Kms."); | |
659 return null; | |
660 } | |
661 | |
662 double step = Double.parseDouble((String) dStep.getValue()); | |
663 | |
664 // transform step from 'm' into 'km' | |
665 step = step / 1000; | |
666 | |
667 if (step == 0d) { | |
668 step = DEFAULT_KM_STEPS; | |
669 } | |
670 | |
671 return DoubleUtil.explode(distance[0], distance[1], step); | |
672 } | |
673 | |
674 | |
675 /** | |
676 * Returns the selected Kms. | |
677 * | |
678 * @return the selected kms. | |
679 */ | |
680 public double[] getKms() { | |
681 if (isRange()) { | |
682 double[] distance = getDistance(); | |
683 return getKms(distance); | |
684 | |
685 } | |
686 else { | |
687 return LocationDistanceSelect.getLocations(this); | |
688 } | |
689 } | |
690 | |
691 public double [] getFromToStep() { | |
692 if (!isRange()) { | |
693 return null; | |
694 } | |
695 double [] fromTo = getDistance(); | |
696 | |
697 if (fromTo == null) { | |
698 return null; | |
699 } | |
700 | |
701 StateData dStep = getData("ld_step"); | |
702 if (dStep == null) { | |
703 return null; | |
704 } | |
705 | |
706 double [] result = new double[3]; | |
707 result[0] = fromTo[0]; | |
708 result[1] = fromTo[1]; | |
709 | |
710 try { | |
711 String step = (String)dStep.getValue(); | |
712 result[2] = DoubleUtil.round(Double.parseDouble(step) / 1000d); | |
713 } | |
714 catch (NumberFormatException nfe) { | |
715 return null; | |
716 } | |
717 | |
718 return result; | |
719 } | |
720 | |
721 | |
722 /** | |
723 * Returns the gauge based on the current distance and river. | |
724 * | |
725 * @return the gauge. | |
726 */ | |
727 public Gauge getGauge() { | |
728 River river = getRiver(); | |
729 | |
730 if (river == null) { | |
731 logger.debug("no river found"); | |
732 return null; | |
733 } | |
734 | |
735 double[] dist = getDistance(); | |
736 | |
737 if (dist == null) { | |
738 logger.debug("no range found"); | |
739 return null; | |
740 } | |
741 | |
742 if (logger.isDebugEnabled()) { | |
743 logger.debug("Determine gauge for:"); | |
744 logger.debug("... river: " + river.getName()); | |
745 logger.debug("... distance: " + dist[0] + " - " + dist[1]); | |
746 } | |
747 | |
748 Gauge gauge = river.determineGauge(dist[0], dist[1]); | |
749 | |
750 String name = gauge != null ? gauge.getName() : "'n/a"; | |
751 logger.debug("Found gauge: " + name); | |
752 | |
753 return gauge; | |
754 } | |
755 | |
756 | |
757 /** | |
758 * Returns the gauges that match the selected kilometer range. | |
759 * | |
760 * @return the gauges based on the selected kilometer range. | |
761 */ | |
762 public List<Gauge> getGauges() { | |
763 | |
764 River river = getRiver(); | |
765 if (river == null) { | |
766 return null; | |
767 } | |
768 | |
769 double [] dist = getDistance(); | |
770 if (dist == null) { | |
771 return null; | |
772 } | |
773 | |
774 return river.determineGauges(dist[0], dist[1]); | |
775 } | |
776 | |
777 | |
778 /** | |
779 * This method returns the Q values. | |
780 * | |
781 * @return the selected Q values or null, if no Q values are selected. | |
782 */ | |
783 public double[] getQs() { | |
784 StateData dMode = getData("wq_mode"); | |
785 StateData dSelection = getData("wq_selection"); | |
786 | |
787 String mode = dMode != null ? (String) dMode.getValue() : ""; | |
788 String sel = dSelection != null ? (String)dSelection.getValue() : null; | |
789 | |
790 if (mode.equals("Q")) { | |
791 if (sel != null && sel.equals("single")) { | |
792 return getSingleWQValues(); | |
793 } | |
794 else { | |
795 return getWQTriple(); | |
796 } | |
797 } | |
798 else { | |
799 logger.warn("You try to get Qs, but W has been inserted."); | |
800 return null; | |
801 } | |
802 } | |
803 | |
804 | |
805 public boolean isQ() { | |
806 StateData mode = getData("wq_mode"); | |
807 return mode != null && mode.getValue().equals("Q"); | |
808 } | |
809 | |
810 | |
811 /** | |
812 * Returns true, if the parameter is set to compute data on a free range. | |
813 * Otherwise it returns false, which tells the calculation that it is bound | |
814 * to a gauge. | |
815 * | |
816 * @return true, if the calculation should compute on a free range otherwise | |
817 * false and the calculation is bound to a gauge. | |
818 */ | |
819 public boolean isFreeQ() { | |
820 StateData mode = getData("wq_free"); | |
821 String value = mode != null ? (String) mode.getValue() : null; | |
822 | |
823 logger.debug("isFreeQ: " + value); | |
824 | |
825 if (value == null) { | |
826 return false; | |
827 } | |
828 | |
829 return Boolean.valueOf(value); | |
830 } | |
831 | |
832 | |
833 /** | |
834 * Returns the Q values based on a specified kilometer range. | |
835 * | |
836 * @param range A 2dim array with lower and upper kilometer range. | |
837 * | |
838 * @return an array of Q values. | |
839 */ | |
840 public double[] getQs(double[] range) { | |
841 StateData dMode = getData("wq_mode"); | |
842 StateData dValues = getData("wq_values"); | |
843 | |
844 String mode = dMode != null ? (String) dMode.getValue() : ""; | |
845 | |
846 if (mode.equals("Q")) { | |
847 return getWQForDist(range); | |
848 } | |
849 | |
850 logger.warn("You try to get Qs, but Ws has been inserted."); | |
851 return null; | |
852 } | |
853 | |
854 | |
855 /** | |
856 * Returns the W values based on a specified kilometer range. | |
857 * | |
858 * @param range A 2dim array with lower and upper kilometer range. | |
859 * | |
860 * @return an array of W values. | |
861 */ | |
862 public double[] getWs(double[] range) { | |
863 StateData dMode = getData("wq_mode"); | |
864 StateData dValues = getData("wq_values"); | |
865 | |
866 String mode = dMode != null ? (String) dMode.getValue() : ""; | |
867 | |
868 if (mode.equals("W")) { | |
869 return getWQForDist(range); | |
870 } | |
871 | |
872 logger.warn("You try to get Ws, but Qs has been inserted."); | |
873 return null; | |
874 } | |
875 | |
876 | |
877 /** | |
878 * This method returns the W values. | |
879 * | |
880 * @return the selected W values or null, if no W values are selected. | |
881 */ | |
882 public double[] getWs() { | |
883 StateData dMode = getData("wq_mode"); | |
884 StateData dSingle = getData("wq_single"); | |
885 | |
886 String mode = dMode != null ? (String) dMode.getValue() : ""; | |
887 | |
888 if (mode.equals("W")) { | |
889 if (dSingle != null) { | |
890 return getSingleWQValues(); | |
891 } | |
892 else { | |
893 return getWQTriple(); | |
894 } | |
895 } | |
896 else { | |
897 logger.warn("You try to get Qs, but W has been inserted."); | |
898 return null; | |
899 } | |
900 } | |
901 | |
902 public List<Segment> getSegments() { | |
903 StateData wqValues = getData("wq_values"); | |
904 if (wqValues == null) { | |
905 logger.warn("no wq_values given"); | |
906 return Collections.emptyList(); | |
907 } | |
908 String input = (String)wqValues.getValue(); | |
909 if (input == null || (input = input.trim()).length() == 0) { | |
910 logger.warn("wq_values are empty"); | |
911 return Collections.emptyList(); | |
912 } | |
913 return Segment.parseSegments(input); | |
914 } | |
915 | |
916 | |
917 /** | |
918 * Returns the Qs for a number of Ws. This method makes use of | |
919 * DischargeTables.getQForW(). | |
920 * | |
921 * @param ws An array of W values. | |
922 * | |
923 * @return an array of Q values. | |
924 */ | |
925 public double[] getQsForWs(double[] ws) { | |
926 | |
927 boolean debug = logger.isDebugEnabled(); | |
928 | |
929 if (debug) { | |
930 logger.debug("FLYSArtifact.getQsForWs"); | |
931 } | |
932 | |
933 River r = getRiver(); | |
934 if (r == null) { | |
935 logger.warn("no river found"); | |
936 return null; | |
937 | |
938 } | |
939 | |
940 double [] range = getDistance(); | |
941 if (range == null) { | |
942 logger.warn("no ranges found"); | |
943 return null; | |
944 } | |
945 | |
946 if (debug) { | |
947 logger.debug("range: " + Arrays.toString(range)); | |
948 } | |
949 | |
950 Gauge g = r.determineGaugeByPosition(range[0]); | |
951 if (g == null) { | |
952 logger.warn("no gauge found for km: " + range[0]); | |
953 return null; | |
954 } | |
955 | |
956 if (debug) { | |
957 logger.debug("convert w->q with gauge '" + g.getName() + "'"); | |
958 } | |
959 | |
960 DischargeTables dt = new DischargeTables(r.getName(), g.getName()); | |
961 Map<String, double [][]> tmp = dt.getValues(); | |
962 | |
963 double[][] values = tmp.get(g.getName()); | |
964 double[] qs = new double[ws.length]; | |
965 | |
966 for (int i = 0; i < ws.length; i++) { | |
967 qs[i] = dt.getQForW(values, ws[i]); | |
968 if (debug) { | |
969 logger.debug("w: " + ws[i] + " -> q: " + qs[i]); | |
970 } | |
971 } | |
972 | |
973 return qs; | |
974 } | |
975 | |
976 /** | |
977 * This method returns the given W or Q values for a specific range | |
978 * (inserted in the WQ input panel for discharge longitudinal sections). | |
979 * | |
980 * @param dist A 2dim array with lower und upper kilometer values. | |
981 * | |
982 * @return an array of W or Q values. | |
983 */ | |
984 protected double[] getWQForDist(double[] dist) { | |
985 logger.debug("Search wq values for range: " + dist[0] + " - " + dist[1]); | |
986 StateData data = getData("wq_values"); | |
987 | |
988 if (data == null) { | |
989 logger.warn("Missing wq values!"); | |
990 return null; | |
991 } | |
992 | |
993 String dataString = (String) data.getValue(); | |
994 String[] ranges = dataString.split(":"); | |
995 | |
996 for (String range: ranges) { | |
997 String[] parts = range.split(";"); | |
998 | |
999 double lower = Double.parseDouble(parts[0]); | |
1000 double upper = Double.parseDouble(parts[1]); | |
1001 | |
1002 if (lower <= dist[0] && upper >= dist[1]) { | |
1003 String[] values = parts[2].split(","); | |
1004 | |
1005 int num = values.length; | |
1006 double[] res = new double[num]; | |
1007 | |
1008 for (int i = 0; i < num; i++) { | |
1009 try { | |
1010 res[i] = Double.parseDouble(values[i]); | |
1011 } | |
1012 catch (NumberFormatException nfe) { | |
1013 logger.warn(nfe, nfe); | |
1014 } | |
1015 } | |
1016 | |
1017 return res; | |
1018 } | |
1019 } | |
1020 | |
1021 logger.warn("Specified range for WQ not found!"); | |
1022 | |
1023 return null; | |
1024 } | |
1025 | |
1026 | |
1027 /** | |
1028 * This method returns an array of inserted WQ triples that consist of from, | |
1029 * to and the step width. | |
1030 * | |
1031 * @return an array of from, to and step width. | |
1032 */ | |
1033 protected double[] getWQTriple() { | |
1034 StateData dFrom = getData("wq_from"); | |
1035 StateData dTo = getData("wq_to"); | |
1036 | |
1037 if (dFrom == null || dTo == null) { | |
1038 logger.warn("Missing start or end value for range."); | |
1039 return null; | |
1040 } | |
1041 | |
1042 double from = Double.parseDouble((String) dFrom.getValue()); | |
1043 double to = Double.parseDouble((String) dTo.getValue()); | |
1044 | |
1045 StateData dStep = getData("wq_step"); | |
1046 | |
1047 if (dStep == null) { | |
1048 logger.warn("No step width given. Cannot compute Qs."); | |
1049 return null; | |
1050 } | |
1051 | |
1052 double step = Double.parseDouble((String) dStep.getValue()); | |
1053 | |
1054 // if no width is given, the DEFAULT_Q_STEPS is used to compute the step | |
1055 // width. Maybe, we should round the value to a number of digits. | |
1056 if (step == 0d) { | |
1057 double diff = to - from; | |
1058 step = diff / DEFAULT_Q_STEPS; | |
1059 } | |
1060 | |
1061 return DoubleUtil.explode(from, to, step); | |
1062 } | |
1063 | |
1064 | |
1065 /** | |
1066 * Returns an array of inserted WQ double values stored as whitespace | |
1067 * separated list. | |
1068 * | |
1069 * @return an array of W or Q values. | |
1070 */ | |
1071 protected double[] getSingleWQValues() { | |
1072 StateData dSingle = getData("wq_single"); | |
1073 | |
1074 if (dSingle == null) { | |
1075 logger.warn("Cannot determine single WQ values. No data given."); | |
1076 return null; | |
1077 } | |
1078 | |
1079 String tmp = (String) dSingle.getValue(); | |
1080 String[] strValues = tmp.split(" "); | |
1081 | |
1082 TDoubleArrayList values = new TDoubleArrayList(); | |
1083 | |
1084 for (String strValue: strValues) { | |
1085 try { | |
1086 values.add(Double.parseDouble(strValue)); | |
1087 } | |
1088 catch (NumberFormatException nfe) { | |
1089 logger.warn(nfe, nfe); | |
1090 } | |
1091 } | |
1092 | |
1093 values.sort(); | |
1094 | |
1095 return values.toNativeArray(); | |
1096 } | 504 } |
1097 | 505 |
1098 | 506 |
1099 /** | 507 /** |
1100 * Computes the hash code of the entered values. | 508 * Computes the hash code of the entered values. |