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