001 /*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2013
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 *
010 * All Rights Reserved
011 *
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.
014 *
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 *
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023 * GNU Lesser Public License for more details.
024 *
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program. If not, see http://www.gnu.org/licenses.
027 */
028
029 package edu.wisc.ssec.mcidasv.data;
030
031 import java.util.ArrayList;
032 import java.util.Collections;
033 import java.util.Comparator;
034 import java.util.HashMap;
035 import java.util.Map;
036
037 import ucar.unidata.data.DataChoice;
038 import ucar.unidata.data.DataContext;
039 import ucar.unidata.data.DataManager;
040 import ucar.unidata.data.DataSource;
041
042 import ucar.unidata.util.TwoFacedObject;
043
044 import ucar.unidata.xml.XmlResourceCollection;
045
046 import edu.wisc.ssec.mcidasv.control.HydraControl;
047 import edu.wisc.ssec.mcidasv.control.MultiSpectralControl;
048
049 import edu.wisc.ssec.mcidasv.display.hydra.MultiSpectralDisplay;
050
051 /**
052 * <p>
053 * The McvDataManager exists purely as a UI nicety. In the IDV, the list of
054 * {@link DataSource}s are presented in the same ordering found in
055 * {@code datasources.xml}.
056 * </p>
057 *
058 * <p>
059 * While ordering the contents of {@code datasources.xml} certainly would have
060 * been easier, the approach taken here is a bit more future-proof. McV simply
061 * sorts the data sources known to the IDV.
062 * </p>
063 */
064 public class McvDataManager extends DataManager {
065
066 /**
067 * ID of the "I'm Still Feeling Lucky" data source. The IDV lowercases it
068 * automatically.
069 */
070 private static final String STILL_LUCKY_ID = "file.any";
071
072 private final Map<DataChoice, HydraControl> hydraDataToControl = new HashMap<DataChoice, HydraControl>();
073 private final Map<DataChoice, MultiSpectralDisplay> hydraDataToDisplay = new HashMap<DataChoice, MultiSpectralDisplay>();
074
075 /**
076 * Default constructor.
077 */
078 public McvDataManager() {
079 super(null);
080 }
081
082 /**
083 * Creates a new DataManager with the given {@link DataContext}.
084 *
085 * @param dataContext The {@code DataContext} that this DataManager exists
086 * within (this is usually an instance of
087 * {@link ucar.unidata.idv.IntegratedDataViewer}).
088 */
089 public McvDataManager(final DataContext dataContext) {
090 super(dataContext);
091 }
092
093 public boolean containsHydraControl(final DataChoice choice) {
094 return hydraDataToControl.containsKey(choice);
095 }
096
097 public boolean containsHydraDisplay(final DataChoice choice) {
098 return hydraDataToDisplay.containsKey(choice);
099 }
100
101 public void setHydraControl(final DataChoice choice, final HydraControl control) {
102 hydraDataToControl.put(choice, control);
103 }
104
105 public void setHydraDisplay(final DataChoice choice, final MultiSpectralDisplay display) {
106 hydraDataToDisplay.put(choice, display);
107 }
108
109 public HydraControl getHydraControl(final DataChoice choice) {
110 return hydraDataToControl.get(choice);
111 }
112
113 public MultiSpectralDisplay getHydraDisplay(final DataChoice choice) {
114 return hydraDataToDisplay.get(choice);
115 }
116
117 /**
118 * Process the list of xml documents that define the different
119 * {@link DataSource}s used within the idv. Overridden so that McIDAS-V
120 * can alphabetize the lists of {@link DataSource}s presented in the UI.
121 *
122 * @param resources The {@link XmlResourceCollection} that holds the set of
123 * datasource xml documents. This may be null.
124 */
125 @Override public void loadDataSourceXml(
126 final XmlResourceCollection resources) {
127 super.loadDataSourceXml(resources);
128 allDataSourceIds = sortTwoFacedObjects(allDataSourceIds);
129 fileDataSourceIds = sortTwoFacedObjects(fileDataSourceIds);
130 }
131
132 /**
133 * <p>
134 * Sorts an {@link ArrayList} of {@link TwoFacedObject}s by label. Case is
135 * ignored.
136 * </p>
137 *
138 * <p>
139 * <b>NOTE:</b> If the ID of one of the objects represents the "I'm Still
140 * Feeling Lucky" data source, it'll always wind up at the end of the list.
141 * </p>
142 *
143 * @param objs The list that needs some sortin' out.
144 *
145 * @return The sorted contents of {@code objs}.
146 */
147 private ArrayList<TwoFacedObject> sortTwoFacedObjects(final ArrayList<TwoFacedObject> objs) {
148 Comparator<TwoFacedObject> comp = new Comparator<TwoFacedObject>() {
149
150 public int compare(final TwoFacedObject a, final TwoFacedObject b) {
151
152 // make sure "I'm still feeling lucky" is always last.
153 if (a.getId().equals(STILL_LUCKY_ID))
154 return 1;
155
156 // same as above!
157 if (b.getId().equals(STILL_LUCKY_ID))
158 return -1;
159
160 // otherwise sorting by label is just fine.
161 return ((String)a.getLabel()).compareToIgnoreCase((String)b.getLabel());
162 }
163
164 @Override public boolean equals(Object o) {
165 return (o == this);
166 }
167 };
168
169 ArrayList<TwoFacedObject> reordered = new ArrayList<TwoFacedObject>(objs);
170 Collections.sort(reordered, comp);
171 return reordered;
172 }
173 }