diff --git a/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml b/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml index b328fd537c..bad6bb8bac 100644 --- a/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.ncep.displays.feature/feature.xml @@ -314,13 +314,6 @@ version="0.0.0" unpack="false"/> - - + + diff --git a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/area/PredefinedAreaFactory.java b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/area/PredefinedAreaFactory.java index 0cbbef340a..efc03aba6a 100644 --- a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/area/PredefinedAreaFactory.java +++ b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/area/PredefinedAreaFactory.java @@ -9,7 +9,6 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,10 +36,11 @@ import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.exception.VizException; /** - * Read and create PredefinedAreas from localization. Also - * - * TODO : add methods to save, delete and edit PredefinedAreas at the USER localization level. - * + * Read and create PredefinedAreas from localization. Also + * + * TODO : add methods to save, delete and edit PredefinedAreas at the USER + * localization level. + * *
  * SOFTWARE HISTORY
  * Date       	Ticket#		Engineer	Description
@@ -58,429 +58,471 @@ import com.raytheon.uf.viz.core.exception.VizException;
  * @author ghull
  * @version 1
  */
-public class PredefinedAreaFactory implements INcAreaProviderFactory {	
-	
-	private static Map predefinedAreasMap = null;
-	
-	private static List badAreas = new ArrayList();
-	
-	public PredefinedAreaFactory() {
-	}
-	
-	@Override
-	public void initialize( String srcName, String dataLoc, String configData ) throws VizException {
-		// should have already been created.
-		AreaSource.createAreaSource( srcName ); 
-		
-		try {
-			readPredefinedAreas();
-		}
-		catch ( VizException v ) {
-			badAreas.add( v ); // should treat this as a real exception instead of just an 
-			                   // invalid area file.
-		}
-	}
-	
-	// read the NMAP areas from localization.
-	// currently, only NcMAP areas are read from localization allow this
-	// could be changed in the future to allow for NonMap NTRANS and
-	// for SWPC displays to have more than the 1 default area.
-	//
-	private void readPredefinedAreas() throws VizException {
-		
-		// only null the first time. Empty if read and error.
-		if( predefinedAreasMap == null ) {
-			predefinedAreasMap = new HashMap();
-			
-			Map areaLocFileMap = NcPathManager.getInstance().listFiles(
-					NcPathConstants.PREDEFINED_AREAS_DIR, new String[]{".xml"}, false, true);
+public class PredefinedAreaFactory implements INcAreaProviderFactory {
 
-			if( areaLocFileMap.isEmpty() ) {
-				throw new VizException(
-						"No Predefined Area Files found under: "+NcPathConstants.PREDEFINED_AREAS_DIR);
-			}
-			
-			boolean dfltFound = false;
-			
-			// to a validity check by unmarshalling each of the files.
-			// Also replace the localizationName (with the PredefinedArea directory prefix
-			// with the name of the area.
-			for( LocalizationFile locF : areaLocFileMap.values() ) {
-				try {
-					PredefinedArea area = getPredefinedArea( locF );
-					
-					if( area.getAreaName().equals( NcDisplayType.NMAP_DISPLAY.getDefaultMap() ) ) {
-						dfltFound = true;
-					}
+    private static Map predefinedAreasMap = null;
 
-					locF.addFileUpdatedObserver( areaFileObserver );
+    private static List badAreas = new ArrayList();
 
-					if( predefinedAreasMap.containsKey( area.getAreaName() ) ) {
-						badAreas.add( 
-								new VizException( "Duplicate Area Name found for :"+ area.getAreaName() ) );
-					}
-					else {
-						predefinedAreasMap.put( area.getAreaName(), locF );
-					}
-				} 
-				catch( VizException ve ) {
-					badAreas.add( ve );
-				}				
-			}
-			
-			if( !dfltFound ) {
-				System.out.println("Could not find valid Default Predefined Area "+ 
-						NcDisplayType.NMAP_DISPLAY.getDefaultMap() );
-			}			
-		}		
-	}
-		
-	@Override
-	public List getAvailableAreaNames() {
-		List areaNames = new ArrayList();
-		
-		for( String aname : getAllAvailAreasForDisplayType() ) {
-			areaNames.add( new AreaName( getAreaSource(), aname ) );
-		}
-		return areaNames;
-	}
+    public PredefinedAreaFactory() {
+    }
 
-	// make sure that the default map is first and maps defined for the main menu are next and then all
-	// the rest.
-	//
-	public static String[] getAllAvailAreasForDisplayType( /*NcDisplayType dispType*/ ) {
-		// if dispType is null then return all types
-		//
-		if( predefinedAreasMap == null ) {
-			System.out.println("getAllAvailPredefinedAreas() called before Areas have been read in.");
-			return new String[0];
-		}
-		
-		List areaNamesList = new ArrayList( predefinedAreasMap.keySet() );
-		String areaNamesArray[] = areaNamesList.toArray( new String[0] );
-		   		   		
-   		return areaNamesArray;
-   	}
-	
-//	// to sort the list of area names. The default goes first
-//	public static class AreaNamesComparator implements Comparator {
-//		private NcDisplayType dispType=NcDisplayType.NMAP_DISPLAY;
-//		
-//		public AreaNamesComparator( NcDisplayType dt ) {
-//			dispType = dt;
-//		}
-//		
-//		@Override
-//		public int compare(String a1, String a2) {
-//			if( a1.equals(a2) ) {
-//				return 0;
-//			}
-//			if( a1.equals( dispType.getDefaultMap() ) ) {
-//				return -1;
-//			}
-//			if( a2.equals( dispType.getDefaultMap() ) ) {
-//				return 1;
-//			}
-//
-//			int a1menuIndx = (areaMenuNames == null ? 999 : (areaMenuNames.contains(a1) ? areaMenuNames.indexOf(a1) : 999) );
-//			int a2menuIndx = (areaMenuNames == null ? 999 : (areaMenuNames.contains(a2) ? areaMenuNames.indexOf(a2) : 999) );
-//			
-//			if( a1menuIndx == a2menuIndx ) { // ie both -1
-//				return a1.compareTo( a2 );
-//			}
-//			return (a1menuIndx < a2menuIndx ? -1 : 1 );
-//		}
-//	} 
-	
-//	// it might be nice create a class specifically to store the predefined 
-//	// area but for now this will just be the Display (we need the zoomLevel and
-//	// mapCenter as well as the gridGeometry)
-//	// 
-	public static PredefinedArea getDefaultPredefinedAreaForDisplayType( NcDisplayType dt ) throws VizException {
-		switch( dt ) {
-		case NMAP_DISPLAY :
-			return getPredefinedArea( dt.getDefaultMap() );
-		case NTRANS_DISPLAY :
-			return createDefaultNonMapArea( dt );
-		case SOLAR_DISPLAY :
-			return createDefaultNonMapArea( dt );
-		}
-		return null;
-	}
+    @Override
+    public void initialize(String srcName, String dataLoc, String configData)
+            throws VizException {
+        // should have already been created.
+        AreaSource.createAreaSource(srcName);
 
-	public static PredefinedArea getPredefinedArea( String areaName ) throws VizException {
-				
-		if( areaName.equals( NcDisplayType.NTRANS_DISPLAY.getDefaultMap() ) ) {
-			return createDefaultNonMapArea(NcDisplayType.NTRANS_DISPLAY );
-		}
-		else if( areaName.equals( NcDisplayType.SOLAR_DISPLAY.getDefaultMap() ) ) {			
-			return createDefaultNonMapArea(NcDisplayType.SOLAR_DISPLAY );
-		}
-		
-//		String key = NcPathConstants.PREDEFINED_AREAS_DIR + File.separator + areaName +".xml";
-		String key = areaName;
-		
-		if( !predefinedAreasMap.containsKey( key ) ) {
-			throw new VizException("Predefined Area : "+ areaName + ", is not in the Areas Map.");
-		}
-		
-		return getPredefinedArea( predefinedAreasMap.get( key ) );
-	}	
-	
-	public static PredefinedArea getPredefinedArea( LocalizationFile lFile ) throws VizException {
-		try {
-			PredefinedArea pa = SerializationUtil.jaxbUnmarshalFromXmlFile( 
-					PredefinedArea.class, lFile.getFile() );
-			
-			// Todo : could fill this in with the filename???
-			if( pa.getAreaName().isEmpty() ) {
-				VizException ve = new VizException( 
-   	   					"Error unmarshaling PredefinedArea: missing AreaName" );
-				throw ve;
-			}
-						
-			return pa;
-			
-		} catch (SerializationException e) {
-			throw new VizException( e );
-		}
+        try {
+            readPredefinedAreas();
+        } catch (VizException v) {
+            badAreas.add(v); // should treat this as a real exception instead of
+                             // just an
+                             // invalid area file.
+        }
+    }
 
-	}
-	
-	public static PredefinedArea clonePredefinedArea( PredefinedArea pArea ) throws VizException { 
+    // read the NMAP areas from localization.
+    // currently, only NcMAP areas are read from localization allow this
+    // could be changed in the future to allow for NonMap NTRANS and
+    // for SWPC displays to have more than the 1 default area.
+    //
+    private void readPredefinedAreas() throws VizException {
 
-		try {
-			File tempRbdFile = File.createTempFile("tempArea-", ".xml");
-			boolean mapCntrIsNull = (pArea.getMapCenter() == null);
-			SerializationUtil.jaxbMarshalToXmlFile( pArea, 
-									tempRbdFile.getAbsolutePath() );
-			String s = null;
-			FileReader fr = new FileReader( tempRbdFile );
-			char[] b = new char[ (int)tempRbdFile.length() ];
-			fr.read(b);
-			fr.close();
-			s = new String(b);
+        // only null the first time. Empty if read and error.
+        if (predefinedAreasMap == null) {
+            predefinedAreasMap = new HashMap();
 
-			pArea = SerializationUtil.unmarshalFromXml( PredefinedArea.class, s );
-			tempRbdFile.delete();
-			
-			// if null this will unmarshall as 0,0
-			if( mapCntrIsNull ) 
-				pArea.setMapCenter( null );
-			return pArea;
-			
-		} catch (SerializationException e) {
-			throw  new VizException( e );
-		} catch (IOException e) { // from createTempFile
-			throw  new VizException( e ); 
-		} catch (JAXBException e) {
-			throw  new VizException( e ); 
-		}
-	}
-	
-	public static PredefinedArea createDefaultNonMapArea( NcDisplayType dt ) {
-		PixelExtent extent = new PixelExtent(0,1000,0,1000);
-		return createDefaultNonMapArea( dt, extent ); 
-	}
-	
-	public static PredefinedArea createPredefinedArea( IGridGeometryProvider geom ) {
-		if( geom == null ) {
-			return null;
-		}
-		else if( geom instanceof PredefinedArea ) {		
-			try {
-				return PredefinedAreaFactory.clonePredefinedArea( (PredefinedArea)geom );
-			} catch (VizException e) {
-				System.out.println("Error cloning PA:"+e.getMessage() );
-				return null;
-			}
-		}
-		return createPredefinedArea( 
-				new AreaName( geom.getSource(), geom.getProviderName() ), geom.getGridGeometry(),
-				              geom.getMapCenter(), geom.getZoomLevel() );
-	}
+            Map areaLocFileMap = NcPathManager
+                    .getInstance().listFiles(
+                            NcPathConstants.PREDEFINED_AREAS_DIR,
+                            new String[] { ".xml" }, false, true);
 
-	public static PredefinedArea createPredefinedArea( 
-			AreaName aName, GeneralGridGeometry geom, double[] mapCntr, String zlvl ) {
-		PredefinedArea parea = new PredefinedArea( aName.getSource(), aName.getName(),
-				geom, mapCntr, zlvl, NcDisplayType.NMAP_DISPLAY );
-		return parea;
-	}
-	
-	public static PredefinedArea createDefaultNonMapArea( NcDisplayType dt, PixelExtent extent ) {
+            if (areaLocFileMap.isEmpty()) {
+                throw new VizException("No Predefined Area Files found under: "
+                        + NcPathConstants.PREDEFINED_AREAS_DIR);
+            }
+
+            boolean dfltFound = false;
+
+            // to a validity check by unmarshalling each of the files.
+            // Also replace the localizationName (with the PredefinedArea
+            // directory prefix
+            // with the name of the area.
+            for (LocalizationFile locF : areaLocFileMap.values()) {
+                try {
+                    PredefinedArea area = getPredefinedArea(locF);
+
+                    if (area.getAreaName().equals(
+                            NcDisplayType.NMAP_DISPLAY.getDefaultMap())) {
+                        dfltFound = true;
+                    }
+
+                    locF.addFileUpdatedObserver(areaFileObserver);
+
+                    if (predefinedAreasMap.containsKey(area.getAreaName())) {
+                        badAreas.add(new VizException(
+                                "Duplicate Area Name found for :"
+                                        + area.getAreaName()));
+                    } else {
+                        predefinedAreasMap.put(area.getAreaName(), locF);
+                    }
+                } catch (VizException ve) {
+                    badAreas.add(ve);
+                }
+            }
+
+            if (!dfltFound) {
+                System.out
+                        .println("Could not find valid Default Predefined Area "
+                                + NcDisplayType.NMAP_DISPLAY.getDefaultMap());
+            }
+        }
+    }
+
+    @Override
+    public List getAvailableAreaNames() {
+        List areaNames = new ArrayList();
+
+        for (String aname : getAllAvailAreasForDisplayType()) {
+            areaNames.add(new AreaName(getAreaSource(), aname));
+        }
+        return areaNames;
+    }
+
+    // make sure that the default map is first and maps defined for the main
+    // menu are next and then all
+    // the rest.
+    //
+    public static String[] getAllAvailAreasForDisplayType( /*
+                                                            * NcDisplayType
+                                                            * dispType
+                                                            */) {
+        // if dispType is null then return all types
+        //
+        if (predefinedAreasMap == null) {
+            System.out
+                    .println("getAllAvailPredefinedAreas() called before Areas have been read in.");
+            return new String[0];
+        }
+
+        List areaNamesList = new ArrayList(
+                predefinedAreasMap.keySet());
+        String areaNamesArray[] = areaNamesList.toArray(new String[0]);
+
+        return areaNamesArray;
+    }
+
+    // // to sort the list of area names. The default goes first
+    // public static class AreaNamesComparator implements Comparator {
+    // private NcDisplayType dispType=NcDisplayType.NMAP_DISPLAY;
+    //
+    // public AreaNamesComparator( NcDisplayType dt ) {
+    // dispType = dt;
+    // }
+    //
+    // @Override
+    // public int compare(String a1, String a2) {
+    // if( a1.equals(a2) ) {
+    // return 0;
+    // }
+    // if( a1.equals( dispType.getDefaultMap() ) ) {
+    // return -1;
+    // }
+    // if( a2.equals( dispType.getDefaultMap() ) ) {
+    // return 1;
+    // }
+    //
+    // int a1menuIndx = (areaMenuNames == null ? 999 :
+    // (areaMenuNames.contains(a1) ? areaMenuNames.indexOf(a1) : 999) );
+    // int a2menuIndx = (areaMenuNames == null ? 999 :
+    // (areaMenuNames.contains(a2) ? areaMenuNames.indexOf(a2) : 999) );
+    //
+    // if( a1menuIndx == a2menuIndx ) { // ie both -1
+    // return a1.compareTo( a2 );
+    // }
+    // return (a1menuIndx < a2menuIndx ? -1 : 1 );
+    // }
+    // }
+
+    // // it might be nice create a class specifically to store the predefined
+    // // area but for now this will just be the Display (we need the zoomLevel
+    // and
+    // // mapCenter as well as the gridGeometry)
+    // //
+    public static PredefinedArea getDefaultPredefinedAreaForDisplayType(
+            NcDisplayType dt) throws VizException {
+        switch (dt) {
+        case NMAP_DISPLAY:
+            return getPredefinedArea(dt.getDefaultMap());
+        case NTRANS_DISPLAY:
+            return createDefaultNonMapArea(dt);
+        case SOLAR_DISPLAY:
+            return createDefaultNonMapArea(dt);
+        case GRAPH_DISPLAY:
+            return createDefaultNonMapArea(dt);
+        }
+        return null;
+    }
+
+    public static PredefinedArea getPredefinedArea(String areaName)
+            throws VizException {
+
+        if (areaName.equals(NcDisplayType.NTRANS_DISPLAY.getDefaultMap())) {
+            return createDefaultNonMapArea(NcDisplayType.NTRANS_DISPLAY);
+        } else if (areaName.equals(NcDisplayType.SOLAR_DISPLAY.getDefaultMap())) {
+            return createDefaultNonMapArea(NcDisplayType.SOLAR_DISPLAY);
+        } else if (areaName.equals(NcDisplayType.GRAPH_DISPLAY.getDefaultMap())) {
+            return createDefaultNonMapArea(NcDisplayType.GRAPH_DISPLAY);
+        }
+
+        // String key = NcPathConstants.PREDEFINED_AREAS_DIR + File.separator +
+        // areaName +".xml";
+        String key = areaName;
+
+        if (!predefinedAreasMap.containsKey(key)) {
+            throw new VizException("Predefined Area : " + areaName
+                    + ", is not in the Areas Map.");
+        }
+
+        return getPredefinedArea(predefinedAreasMap.get(key));
+    }
+
+    public static PredefinedArea getPredefinedArea(LocalizationFile lFile)
+            throws VizException {
+        try {
+            PredefinedArea pa = SerializationUtil.jaxbUnmarshalFromXmlFile(
+                    PredefinedArea.class, lFile.getFile());
+
+            // Todo : could fill this in with the filename???
+            if (pa.getAreaName().isEmpty()) {
+                VizException ve = new VizException(
+                        "Error unmarshaling PredefinedArea: missing AreaName");
+                throw ve;
+            }
+
+            return pa;
+
+        } catch (SerializationException e) {
+            throw new VizException(e);
+        }
+
+    }
+
+    public static PredefinedArea clonePredefinedArea(PredefinedArea pArea)
+            throws VizException {
+
+        try {
+            File tempRbdFile = File.createTempFile("tempArea-", ".xml");
+            boolean mapCntrIsNull = (pArea.getMapCenter() == null);
+            SerializationUtil.jaxbMarshalToXmlFile(pArea,
+                    tempRbdFile.getAbsolutePath());
+            String s = null;
+            FileReader fr = new FileReader(tempRbdFile);
+            char[] b = new char[(int) tempRbdFile.length()];
+            fr.read(b);
+            fr.close();
+            s = new String(b);
+
+            pArea = SerializationUtil.unmarshalFromXml(PredefinedArea.class, s);
+            tempRbdFile.delete();
+
+            // if null this will unmarshall as 0,0
+            if (mapCntrIsNull)
+                pArea.setMapCenter(null);
+            return pArea;
+
+        } catch (SerializationException e) {
+            throw new VizException(e);
+        } catch (IOException e) { // from createTempFile
+            throw new VizException(e);
+        } catch (JAXBException e) {
+            throw new VizException(e);
+        }
+    }
+
+    public static PredefinedArea createDefaultNonMapArea(NcDisplayType dt) {
+        PixelExtent extent = new PixelExtent(0, 1000, 0, 1000);
+        return createDefaultNonMapArea(dt, extent);
+    }
+
+    public static PredefinedArea createPredefinedArea(IGridGeometryProvider geom) {
+        if (geom == null) {
+            return null;
+        } else if (geom instanceof PredefinedArea) {
+            try {
+                return PredefinedAreaFactory
+                        .clonePredefinedArea((PredefinedArea) geom);
+            } catch (VizException e) {
+                System.out.println("Error cloning PA:" + e.getMessage());
+                return null;
+            }
+        }
+        return createPredefinedArea(
+                new AreaName(geom.getSource(), geom.getProviderName()),
+                geom.getGridGeometry(), geom.getMapCenter(),
+                geom.getZoomLevel());
+    }
+
+    public static PredefinedArea createPredefinedArea(AreaName aName,
+            GeneralGridGeometry geom, double[] mapCntr, String zlvl) {
+        PredefinedArea parea = new PredefinedArea(aName.getSource(),
+                aName.getName(), geom, mapCntr, zlvl,
+                NcDisplayType.NMAP_DISPLAY);
+        return parea;
+    }
+
+    public static PredefinedArea createDefaultNonMapArea(NcDisplayType dt,
+            PixelExtent extent) {
 
         GeneralEnvelope envelope = new GeneralEnvelope(2);
         envelope.setRange(0, extent.getMinX(), extent.getMaxX());
         envelope.setRange(1, extent.getMinY(), extent.getMaxY());
-        envelope.setCoordinateReferenceSystem( DefaultEngineeringCRS.CARTESIAN_2D );
-        GeneralGridGeometry geom = new GridGeometry2D(
-                new GeneralGridEnvelope(new int[] { 0, 0 }, new int[] {
-                        (int) extent.getWidth(), (int) extent.getHeight() },
-                        false), envelope);
+        envelope.setCoordinateReferenceSystem(DefaultEngineeringCRS.CARTESIAN_2D);
+        GeneralGridGeometry geom = new GridGeometry2D(new GeneralGridEnvelope(
+                new int[] { 0, 0 }, new int[] { (int) extent.getWidth(),
+                        (int) extent.getHeight() }, false), envelope);
 
-        return new PredefinedArea( AreaSource.PREDEFINED_AREA, dt.getDefaultMap(),
-								   geom, new double[]{500,500}, "1.0", dt );
-	}
-	
-	private static ILocalizationFileObserver areaFileObserver = new ILocalizationFileObserver() {
-		@Override
-		public void fileUpdated( FileUpdatedMessage fumsg) {
-			if( predefinedAreasMap == null ) {
-				return;// should be impossible
-			}
+        return new PredefinedArea(AreaSource.PREDEFINED_AREA,
+                dt.getDefaultMap(), geom, new double[] { 500, 500 }, "1.0", dt);
+    }
 
-			// first need to remove the entry for the updated file from the
-			// map. Do it this way to best handle the case when a user changes the 
-			// area name in an existing file.
-			// 
-			String keyToRemove = null;
-			
-			for( Entry areaEntry : predefinedAreasMap.entrySet() ) {
-				LocalizationFile lf = areaEntry.getValue();
-				
-				// ?? check the context too?
-				if( fumsg.getFileName().equals( lf.getName() ) ) {
-					lf.removeFileUpdatedObserver( areaFileObserver );
-					keyToRemove = areaEntry.getKey();
-					break;
-				}
-			}
-			
-			try {   synchronized ( predefinedAreasMap ) {
+    private static ILocalizationFileObserver areaFileObserver = new ILocalizationFileObserver() {
+        @Override
+        public void fileUpdated(FileUpdatedMessage fumsg) {
+            if (predefinedAreasMap == null) {
+                return;// should be impossible
+            }
 
-				if( keyToRemove != null ) {
-					predefinedAreasMap.remove( keyToRemove );
-				}
-				else { /// ????
-					System.out.println("sanity check: Area fileUpated(): couldn't find locFile name in the Area Map???");
-				}
-			
-			// if added or updated, update the loc file in the map.
-			// else if deleted then check for another version of the file and 'revert'
-				LocalizationFile locFile;
-				PredefinedArea area;
+            // first need to remove the entry for the updated file from the
+            // map. Do it this way to best handle the case when a user changes
+            // the
+            // area name in an existing file.
+            //
+            String keyToRemove = null;
 
-				if( fumsg.getChangeType() == FileChangeType.ADDED ||
-					fumsg.getChangeType() == FileChangeType.UPDATED ) {
+            for (Entry areaEntry : predefinedAreasMap
+                    .entrySet()) {
+                LocalizationFile lf = areaEntry.getValue();
 
-					locFile = NcPathManager.getInstance().getLocalizationFile( 
-													fumsg.getContext(), fumsg.getFileName() );
-					if( locFile != null ) {
-						area = getPredefinedArea( locFile );
-					
-						// since the existing entry should have been removed, this means 
-						// they have changed the name to a name that already exists. 
-						if( predefinedAreasMap.containsKey( area.getAreaName() ) ) {
-							System.out.println("Area fileUpdated: area "+area.getAreaName() +
-									" is already defined in another LocalizationFile: "+
-									predefinedAreasMap.get( area.getAreaName() ).getName() );
-						} // else ?????
-						else {
-							locFile.addFileUpdatedObserver( areaFileObserver );
+                // ?? check the context too?
+                if (fumsg.getFileName().equals(lf.getName())) {
+                    lf.removeFileUpdatedObserver(areaFileObserver);
+                    keyToRemove = areaEntry.getKey();
+                    break;
+                }
+            }
 
-							predefinedAreasMap.put( area.getAreaName(), locFile );
-						}						
-					}
-				}
-				else if( fumsg.getChangeType() == FileChangeType.DELETED ) {
-					locFile = NcPathManager.getInstance().getStaticLocalizationFile( 
-							fumsg.getFileName() );
-					if( locFile != null ) {
-						area = getPredefinedArea( locFile );
+            try {
+                synchronized (predefinedAreasMap) {
 
-						// shouldn't happen.
-						if( locFile.getContext().getLocalizationLevel() == 
-							                        LocalizationLevel.USER ) {
-							System.out.println("sanity check: loc file deleted but still found a user-level version???");
-						}
-						else {
-							locFile.addFileUpdatedObserver( areaFileObserver );
+                    if (keyToRemove != null) {
+                        predefinedAreasMap.remove(keyToRemove);
+                    } else { // / ????
+                        System.out
+                                .println("sanity check: Area fileUpated(): couldn't find locFile name in the Area Map???");
+                    }
 
-							predefinedAreasMap.put( area.getAreaName(), locFile );							
-						}
-					}
-				}
-			}
-			} catch (VizException e) {
-				System.out.println("Error Updateing Areas Map from Localization Update???");
-				return;
-			}
-		}
-	};
+                    // if added or updated, update the loc file in the map.
+                    // else if deleted then check for another version of the
+                    // file and 'revert'
+                    LocalizationFile locFile;
+                    PredefinedArea area;
 
-	@Override
-	public AreaSource getAreaSource() {
-		return AreaSource.PREDEFINED_AREA;//areaSource;
-	}
+                    if (fumsg.getChangeType() == FileChangeType.ADDED
+                            || fumsg.getChangeType() == FileChangeType.UPDATED) {
 
-	@Override
-	public IGridGeometryProvider createGeomProvider( String areaName )
-			throws VizException {
-		return getPredefinedArea( areaName );
-	}
+                        locFile = NcPathManager.getInstance()
+                                .getLocalizationFile(fumsg.getContext(),
+                                        fumsg.getFileName());
+                        if (locFile != null) {
+                            area = getPredefinedArea(locFile);
 
-	@Override
-	public List getInitializationExceptions() {
-		return badAreas;
-	}
-	
-	public static PredefinedArea savePredefinedArea( IGridGeometryProvider geomProv,
-			                               String areaname, boolean overwrite ) throws VizException {
-		
-		LocalizationFile lfile = predefinedAreasMap.get( areaname );
-		boolean areaExists = (lfile != null);
-		if( !overwrite && areaExists ) {
-			throw new VizException("A predefined area, "+areaname+", already exists");
-		}
+                            // since the existing entry should have been
+                            // removed, this means
+                            // they have changed the name to a name that already
+                            // exists.
+                            if (predefinedAreasMap.containsKey(area
+                                    .getAreaName())) {
+                                System.out
+                                        .println("Area fileUpdated: area "
+                                                + area.getAreaName()
+                                                + " is already defined in another LocalizationFile: "
+                                                + predefinedAreasMap.get(
+                                                        area.getAreaName())
+                                                        .getName());
+                            } // else ?????
+                            else {
+                                locFile.addFileUpdatedObserver(areaFileObserver);
 
-		PredefinedArea parea = PredefinedAreaFactory.createPredefinedArea( geomProv );
-		
-		if( parea == null ) {
-			throw new VizException( "Error creating PredefinedArea for: "+
-					geomProv.getSource()+"/"+geomProv.getProviderName() );
-		}
-		AreaName pareaName = new AreaName( AreaSource.PREDEFINED_AREA, areaname );
-		parea.setAreaName( areaname );
-		parea.setAreaSource( AreaSource.PREDEFINED_AREA.toString() );
-		
-		if( !areaExists ) {
-			LocalizationContext usrCntxt = NcPathManager.getInstance().getContext(
-    				LocalizationType.CAVE_STATIC, LocalizationLevel.USER );
-			String lname = NcPathConstants.PREDEFINED_AREAS_DIR+File.separator+areaname+".xml";
-			
-			lfile = NcPathManager.getInstance().getLocalizationFile( usrCntxt, lname );
+                                predefinedAreasMap.put(area.getAreaName(),
+                                        locFile);
+                            }
+                        }
+                    } else if (fumsg.getChangeType() == FileChangeType.DELETED) {
+                        locFile = NcPathManager.getInstance()
+                                .getStaticLocalizationFile(fumsg.getFileName());
+                        if (locFile != null) {
+                            area = getPredefinedArea(locFile);
 
-			if( lfile == null ) {
-				throw new VizException("Error saving Predefined Area, "+areaname+
-						": error creatinge localization File.");
-			}			
-		}
-			
-		try {
-			SerializationUtil.jaxbMarshalToXmlFile( parea, 
-					lfile.getFile().getAbsolutePath() );
-			lfile.save();
+                            // shouldn't happen.
+                            if (locFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) {
+                                System.out
+                                        .println("sanity check: loc file deleted but still found a user-level version???");
+                            } else {
+                                locFile.addFileUpdatedObserver(areaFileObserver);
 
-			if( !areaExists ) {
-				lfile.addFileUpdatedObserver( areaFileObserver );
-				predefinedAreasMap.put( areaname, lfile );
-			}
-			
-			return parea;
-		} 
-		catch (LocalizationOpFailedException e) {
-			throw new VizException("Error saving Predefined Area, "+areaname+
-					": "+e.getMessage() );
-		} 
-		catch (SerializationException e) {
-			throw new VizException("Error saving Predefined Area, "+areaname+
-					": "+e.getMessage() );
-		}		
-	}
-//	@Override
-//	public void setInitializationData(IConfigurationElement config,
-//			String propertyName, Object data) throws CoreException {
-//		System.out.println("setInitializationData called with propertyName "+
-//				propertyName+ " = "+(data == null ? "null" : data.toString()) );
-//	}
+                                predefinedAreasMap.put(area.getAreaName(),
+                                        locFile);
+                            }
+                        }
+                    }
+                }
+            } catch (VizException e) {
+                System.out
+                        .println("Error Updateing Areas Map from Localization Update???");
+                return;
+            }
+        }
+    };
+
+    @Override
+    public AreaSource getAreaSource() {
+        return AreaSource.PREDEFINED_AREA;// areaSource;
+    }
+
+    @Override
+    public IGridGeometryProvider createGeomProvider(String areaName)
+            throws VizException {
+        return getPredefinedArea(areaName);
+    }
+
+    @Override
+    public List getInitializationExceptions() {
+        return badAreas;
+    }
+
+    public static PredefinedArea savePredefinedArea(
+            IGridGeometryProvider geomProv, String areaname, boolean overwrite)
+            throws VizException {
+
+        LocalizationFile lfile = predefinedAreasMap.get(areaname);
+        boolean areaExists = (lfile != null);
+        if (!overwrite && areaExists) {
+            throw new VizException("A predefined area, " + areaname
+                    + ", already exists");
+        }
+
+        PredefinedArea parea = PredefinedAreaFactory
+                .createPredefinedArea(geomProv);
+
+        if (parea == null) {
+            throw new VizException("Error creating PredefinedArea for: "
+                    + geomProv.getSource() + "/" + geomProv.getProviderName());
+        }
+        AreaName pareaName = new AreaName(AreaSource.PREDEFINED_AREA, areaname);
+        parea.setAreaName(areaname);
+        parea.setAreaSource(AreaSource.PREDEFINED_AREA.toString());
+
+        if (!areaExists) {
+            LocalizationContext usrCntxt = NcPathManager.getInstance()
+                    .getContext(LocalizationType.CAVE_STATIC,
+                            LocalizationLevel.USER);
+            String lname = NcPathConstants.PREDEFINED_AREAS_DIR
+                    + File.separator + areaname + ".xml";
+
+            lfile = NcPathManager.getInstance().getLocalizationFile(usrCntxt,
+                    lname);
+
+            if (lfile == null) {
+                throw new VizException("Error saving Predefined Area, "
+                        + areaname + ": error creatinge localization File.");
+            }
+        }
+
+        try {
+            SerializationUtil.jaxbMarshalToXmlFile(parea, lfile.getFile()
+                    .getAbsolutePath());
+            lfile.save();
+
+            if (!areaExists) {
+                lfile.addFileUpdatedObserver(areaFileObserver);
+                predefinedAreasMap.put(areaname, lfile);
+            }
+
+            return parea;
+        } catch (LocalizationOpFailedException e) {
+            throw new VizException("Error saving Predefined Area, " + areaname
+                    + ": " + e.getMessage());
+        } catch (SerializationException e) {
+            throw new VizException("Error saving Predefined Area, " + areaname
+                    + ": " + e.getMessage());
+        }
+    }
+    // @Override
+    // public void setInitializationData(IConfigurationElement config,
+    // String propertyName, Object data) throws CoreException {
+    // System.out.println("setInitializationData called with propertyName "+
+    // propertyName+ " = "+(data == null ? "null" : data.toString()) );
+    // }
 }
diff --git a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java
index 5f5f821e84..4c357abdc2 100644
--- a/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java
+++ b/ncep/gov.noaa.nws.ncep.viz.common/src/gov/noaa/nws/ncep/viz/common/display/NcDisplayType.java
@@ -7,7 +7,6 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
-
 /**
  * 
  * 
@@ -15,92 +14,94 @@ import javax.xml.bind.annotation.XmlRootElement;
  * Date       	Ticket#		Engineer	Description
  * ------------	----------	-----------	--------------------------
  *  02/10/13      #972        Greg Hull   Created
- *
+ * 
  * 
* * @author ghull * @version 1 */ -// an RBD must be one of these display types and all resources in the RBD must be compatible -// with the display type. +// an RBD must be one of these display types and all resources in the RBD must +// be compatible +// with the display type. @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public enum NcDisplayType { - // could make this a class and populate from an extension point. - - NMAP_DISPLAY( "NC-MAP", - // the NcPaneManager knows the display type handles differences appropriately - "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", - "BasicWX_US", - "OVERLAY/GeoPolitical/default", - true), - NTRANS_DISPLAY( "NTRANS", - "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", - "DefaultCanvas", - "", - true), - SOLAR_DISPLAY( "SOLAR", - "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", - "DefaultCanvas", - "", - true), - -// CURRENTLY NOT USED, - NSHARP_DISPLAY( "NSHARP", - "gov.noaa.nws.ncep.ui.nsharp.display.NcNsharpPaneManager", - "BasicWX_US", - "OVERLAY/GeoPolitical/default", - false ); -// NC_TIME_SERIES_DISPLAY, -// NC_CROSS_SECTION_DISPLAY; - +public enum NcDisplayType { + // could make this a class and populate from an extension point. + + NMAP_DISPLAY( + "NC-MAP", + // the NcPaneManager knows the display type handles differences + // appropriately + "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", "BasicWX_US", + "OVERLAY/GeoPolitical/default", true), + + NTRANS_DISPLAY("NTRANS", "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", + "DefaultCanvas", "", true), + + SOLAR_DISPLAY("SOLAR", "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", + "DefaultCanvas", "", true), + + // CURRENTLY NOT USED, + NSHARP_DISPLAY("NSHARP", + "gov.noaa.nws.ncep.ui.nsharp.display.NcNsharpPaneManager", + "BasicWX_US", "OVERLAY/GeoPolitical/default", false), + + GRAPH_DISPLAY("GRAPH", "gov.noaa.nws.ncep.viz.ui.display.NCPaneManager", + "DefaultCanvas", "", true); + // NC_TIME_SERIES_DISPLAY, + // NC_CROSS_SECTION_DISPLAY; + + private String dispType; + + private String paneManager; + + private String defaultArea; // ie the gridGeom/CRS, zoomlevel, mapcenter. + + private String baseResource; // if applicable, null if not + + private Boolean isSavable; // can this be saved to an rbd. + + private NcDisplayType(String dtstr, String pMngr, String area, + String baseOvrly, Boolean canSave) { + dispType = dtstr; + paneManager = pMngr; + defaultArea = area; + baseResource = baseOvrly; + isSavable = canSave; + } + + public String getName() { + return dispType; + } + + public static NcDisplayType getDisplayType(String dts) { + for (NcDisplayType dt : NcDisplayType.values()) { + if (dts.equalsIgnoreCase(dt.getName())) { + return dt; + } + } + return null; + } + + public static List getRbdSavableDisplayTypes() { + List dtl = new ArrayList(); + for (NcDisplayType dt : values()) { + if (dt.isSavable) { + dtl.add(dt); + } + } + return dtl; + } - private String dispType; - private String paneManager; - private String defaultArea; // ie the gridGeom/CRS, zoomlevel, mapcenter. - private String baseResource; // if applicable, null if not - private Boolean isSavable; // can this be saved to an rbd. - - private NcDisplayType( String dtstr, String pMngr, String area, String baseOvrly, Boolean canSave ) { - dispType = dtstr; - paneManager = pMngr; - defaultArea = area; - baseResource = baseOvrly; - isSavable = canSave; - } - - public String getName() { - return dispType; - } - - public static NcDisplayType getDisplayType( String dts ) { - for( NcDisplayType dt : NcDisplayType.values() ) { - if( dts.equalsIgnoreCase( dt.getName() ) ) { - return dt; - } - } - return null; - } - - public static List getRbdSavableDisplayTypes() { - List dtl = new ArrayList(); - for( NcDisplayType dt : values() ) { - if( dt.isSavable ) { - dtl.add( dt ); - } - } - return dtl; - } - public String getPaneManager() { - return paneManager; - } + return paneManager; + } - public void setPaneManager(String paneManager) { - this.paneManager = paneManager; - } + public void setPaneManager(String paneManager) { + this.paneManager = paneManager; + } - public String getDefaultMap() { + public String getDefaultMap() { return defaultArea; } @@ -108,7 +109,7 @@ public enum NcDisplayType { return baseResource; } - public Boolean getIsRbdSavable() { - return isSavable; - } + public Boolean getIsRbdSavable() { + return isSavable; + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DIRECT.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DIRECT.xml new file mode 100644 index 0000000000..2beafd5b1e --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DIRECT.xml @@ -0,0 +1,6 @@ + + + GEOMAG + DIRECT + H_Direct,D_Direct,HQdc_Direct,DQdc_Direct + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DOMSAT.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DOMSAT.xml new file mode 100644 index 0000000000..a780119a48 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DOMSAT.xml @@ -0,0 +1,6 @@ + + + GEOMAG + DOMSAT + H_Domsat,D_Domsat,HQdc_Domsat,DQdc_Domsat + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DQdc_Direct.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DQdc_Direct.attr new file mode 100644 index 0000000000..6262d1e6dc --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DQdc_Direct.attr @@ -0,0 +1,6 @@ +sourceId=101 +yAxesData=DQdc +dataColor=light blue +xAxesTitle=Time (hr) +yAxesTitle=DQdc (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DQdc_Domsat.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DQdc_Domsat.attr new file mode 100644 index 0000000000..45faaa1f75 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/DQdc_Domsat.attr @@ -0,0 +1,6 @@ +sourceId=103 +yAxesData=DQdc +dataColor=light blue +xAxesTitle=Time (hr) +yAxesTitle=DQdc (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Direct.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Direct.attr new file mode 100644 index 0000000000..9e8fab6974 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Direct.attr @@ -0,0 +1,6 @@ +sourceId=101 +yAxesData=D +dataColor=dodger blue +xAxesTitle=Time (hr) +yAxesTitle=D (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Domsat.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Domsat.attr new file mode 100644 index 0000000000..ccbdca74a3 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Domsat.attr @@ -0,0 +1,6 @@ +sourceId=103 +yAxesData=D +dataColor=dodger blue +xAxesTitle=Time (hr) +yAxesTitle=D (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Magworm.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Magworm.attr new file mode 100644 index 0000000000..bde71b4754 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/D_Magworm.attr @@ -0,0 +1,6 @@ +sourceId=102 +yAxesData=D +dataColor=dodger blue +xAxesTitle=Time (hr) +yAxesTitle=D (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/HQdc_Direct.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/HQdc_Direct.attr new file mode 100644 index 0000000000..3bb5bcf2c7 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/HQdc_Direct.attr @@ -0,0 +1,6 @@ +sourceId=101 +yAxesData=HQdc +dataColor=pink +xAxesTitle=Time (hr) +yAxesTitle=HQdc (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/HQdc_Domsat.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/HQdc_Domsat.attr new file mode 100644 index 0000000000..a366a01996 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/HQdc_Domsat.attr @@ -0,0 +1,6 @@ +sourceId=103 +yAxesData=HQdc +dataColor=pink +xAxesTitle=Time (hr) +yAxesTitle=HQdc (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/H_Direct.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/H_Direct.attr new file mode 100644 index 0000000000..00bf3065a2 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/H_Direct.attr @@ -0,0 +1,6 @@ +sourceId=101 +yAxesData=H +dataColor=red +xAxesTitle=Time (hr) +yAxesTitle=H (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/H_Domsat.attr b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/H_Domsat.attr new file mode 100644 index 0000000000..6ec7884f54 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/H_Domsat.attr @@ -0,0 +1,6 @@ +sourceId=103 +yAxesData=H +dataColor=red +xAxesTitle=Time (hr) +yAxesTitle=H (nT) +yDescription=Baseline \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/MAGWORM.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/MAGWORM.xml new file mode 100644 index 0000000000..f2f8800d7b --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/AttributeSetGroups/GeoMag/MAGWORM.xml @@ -0,0 +1,6 @@ + + + GEOMAG + MAGWORM + H_Magworm,D_Magworm,HQdc_Magworm,DQdc_Magworm + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml index e1444fc9e6..3d5c170ab4 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/ResourceFilters.xml @@ -1446,4 +1446,7 @@ Forecast,SWPC - + +Forecast,SWPC + + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/TIMESERIES/GEOMAG/GEOMAG.xml b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/TIMESERIES/GEOMAG/GEOMAG.xml new file mode 100644 index 0000000000..c4f677d889 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.localization/localization/ncep/ResourceDefns/TIMESERIES/GEOMAG/GEOMAG.xml @@ -0,0 +1,21 @@ + + + GEOMAG + false + TIMESERIES + +pluginName=geomag +reportType=GEOMAG + + GeoMag + + stationCode + EXACT + 12 + 3 + 1 + USE_DATA_TIMES + 1 + 24 + BasicWX_US + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java b/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java index 3a0e293617..719cae6492 100644 --- a/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java +++ b/ncep/gov.noaa.nws.ncep.viz.localization/src/gov/noaa/nws/ncep/viz/localization/NcPathManager.java @@ -6,23 +6,22 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; -import com.raytheon.uf.common.localization.LocalizationFile; -import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.viz.core.localization.CAVELocalizationAdapter; import com.raytheon.uf.viz.core.localization.LocalizationManager; - /** - * A Facade over the PathManager. This was initially created to create a pathMngr with - * a NatlCntrsLocalizationAdapter but now is just a convenience wrapper around the - * same PathManager as the rest of CAVE. - * - Would it be ok/better to derive from PathManager directly and bypass the PathManagerFactory? + * A Facade over the PathManager. This was initially created to create a + * pathMngr with a NatlCntrsLocalizationAdapter but now is just a convenience + * wrapper around the same PathManager as the rest of CAVE. + * + * Would it be ok/better to derive from PathManager directly and bypass the + * PathManagerFactory? * *
  * SOFTWARE HISTORY
@@ -51,308 +50,458 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager;
  * 04/10/2013     #958      qzhou        Added SOLAR_IMG_STYLE_RULES
  * 05/15/2013     #862      Greg Hull    AreaMenus tbl to xml
  * 11/15/2013     #1051     Greg Hull    createDeskLevel() called from NmapCommon and triggered by spring.
- * 
+ * 06/18/2014     #1131     qzhou        Added DFLT_GRAPH_RBD
  * 
* - * @author ghull + * @author ghull * @version 1 */ public class NcPathManager { - private static NcPathManager ncPathMngr = null; - private static IPathManager pathMngr = null; + private static NcPathManager ncPathMngr = null; - // we could instead read from the extension point to find the relative path for a 'type' of file. - // - public static class NcPathConstants { + private static IPathManager pathMngr = null; - public static final String DESK_LEVEL = "DESK"; - - // the root of NCEP file hierarchy (below base/user/site/desk) - public static final String NCEP_ROOT = "ncep"+File.separator; + // we could instead read from the extension point to find the relative path + // for a 'type' of file. + // + public static class NcPathConstants { - // Note that these files are in STATIC_COMMON - public static final String NCINVENTORY_DEFNS_DIR = NCEP_ROOT + "NcInventoryDefinitions"; + public static final String DESK_LEVEL = "DESK"; - // static directories. - public static final String SPFS_DIR = NCEP_ROOT + "SPFs"; // the Groups dir - public static final String RSC_TMPLTS_DIR = NCEP_ROOT + "resourceTemplates"; - public static final String RSC_DEFNS_DIR = NCEP_ROOT + "ResourceDefns"; - public static final String ATTR_SET_GROUPS_DIR = NCEP_ROOT + "AttributeSetGroups"; - public static final String PREDEFINED_AREAS_DIR= NCEP_ROOT + "PredefinedAreas"; - public static final String COLORBARS_DIR = NCEP_ROOT + "ColorBars"; - public static final String COLORMAPS_DIR = NCEP_ROOT + "ColorMaps"; - public static final String STATIONS_DIR = NCEP_ROOT + "Stations"; - public static final String LOGOS_DIR = NCEP_ROOT + "Logos"; - public static final String CURSORS_DIR = NCEP_ROOT + "Cursors"; - public static final String PLOT_MODELS_DIR = NCEP_ROOT + "PlotModels"; - public static final String PLOT_PARAMETERS_DIR = PLOT_MODELS_DIR + File.separator+"PlotParameters"; - public static final String FONT_FILES_DIR = NCEP_ROOT + "fontFiles" + File.separator ; - public static final String LOCATOR_SOURCE_DIR = NCEP_ROOT+"LocatorDataSources"; + // the root of NCEP file hierarchy (below base/user/site/desk) + public static final String NCEP_ROOT = "ncep" + File.separator; - public static final String RESOURCE_FILTERS = RSC_DEFNS_DIR+ File.separator+"ResourceFilters.xml"; - public static final String AREA_MENUS_FILE = PREDEFINED_AREAS_DIR + File.separator+ - "menus"+ File.separator+"AreaMenus.xml"; - -// No longer used. location is now a parameter for the StaticPgenOverlayResource. -// public static final String PGEN_XML_OVERLAYS = NCEP_ROOT + "StaticPgenOverlays"; - public static final String STYLE_RULES_DIR = NCEP_ROOT + "styleRules" + File.separator; - // lpi,spi files for overlays - public static final String BASEMAPS_DIR = NCEP_ROOT + "basemaps"; - - // static files - public static final String DFLT_RBD = NCEP_ROOT + "DefaultRBDs" + File.separator+"defaultRBD.xml"; - public static final String DFLT_NTRANS_RBD = NCEP_ROOT + "DefaultRBDs" + File.separator+"defaultNTransRBD.xml"; - public static final String DFLT_SOLAR_RBD = NCEP_ROOT + "DefaultRBDs" + File.separator+"defaultSolarRBD.xml"; - - public static final String LOCATOR_TBL = NCEP_ROOT+"Locator"+File.separator+"locator_tbl.xml"; - public static final String LOGOS_TBL = NCEP_ROOT + "Logos" + File.separator + "logos.tbl"; - public static final String LOOP_SPEEDS_TBL= NCEP_ROOT + "LoopControls"+ - File.separator+"loopSpeeds.tbl"; - public static final String LOCKED_CMAP_TBL = NcPathConstants.COLORMAPS_DIR + File.separator + "lockedColorMaps.tbl"; - public static final String CURSOR_REFS_TBL= CURSORS_DIR + File.separator + "cursorref_tbl.xml"; + // Note that these files are in STATIC_COMMON + public static final String NCINVENTORY_DEFNS_DIR = NCEP_ROOT + + "NcInventoryDefinitions"; - public static final String CLOUD_HEIGHT_SOUNDING_MODELS = - NCEP_ROOT+"CloudHeight"+File.separator+"SoundingModels.xml"; - - public static final String GEOG_TBL = PREDEFINED_AREAS_DIR + File.separator+ - "gempak"+File.separator+"geog.xml"; - public static final String SFSTNS_TBL = STATIONS_DIR+File.separator+"sfstns.xml"; - - public static final String CONDITIONAL_FILTERS_DIR = PLOT_MODELS_DIR + File.separator+"ConditionalFilters"; - public static final String CONDITIONAL_FILTER_HELP_FILE = NCEP_ROOT + File.separator + "conditionalFilter" + File.separator + "ConditionalFilterHelp.txt"; - public static final String CONDITIONAL_FILTER_MINUS_IMG = NCEP_ROOT + File.separator + "conditionalFilter" + File.separator + "minus_red.gif"; - public static final String CONDITIONAL_FILTER_PLUS_IMG = NCEP_ROOT + File.separator + "conditionalFilter" + File.separator + "plus_green.gif"; - public static final String ADVANCED_ICON_IMG = NCEP_ROOT + File.separator + "advanced" + File.separator + "adv_icon.jpg"; - - // migrating code which looked for these filenames - public static final String VORS_STN_TBL = STATIONS_DIR + File.separator+"vors.xml"; - public static final String VOLCANO_STN_TBL = STATIONS_DIR + File.separator+"volcano.xml"; - public static final String COUNTY_STN_TBL = STATIONS_DIR + File.separator+ "county.xml"; - public static final String FFG_ZONES_STN_TBL = STATIONS_DIR + File.separator+"ffgZones.xml"; - public static final String SPCWATCH_STN_TBL = STATIONS_DIR + File.separator+"spcwatch.xml"; - public static final String SHAPEFILES_DIR = NCEP_ROOT + "Shapefiles"; + // static directories. + public static final String SPFS_DIR = NCEP_ROOT + "SPFs"; // the Groups + // dir - public static final String SEEK_STN_TBL = NCEP_ROOT + "Seek"+File.separator+"seekStns.xml"; + public static final String RSC_TMPLTS_DIR = NCEP_ROOT + + "resourceTemplates"; -// public static final String GRID_DATATYPE_TBL = NCEP_ROOT + "grid"+File.separator+"datatype.tbl"; -// public static final String ENSEMBLE_MODELS_TBL= NCEP_ROOT + "grid"+File.separator+"ensemble_models.tbl"; - public static final String GEMPAK_MARKER_TYPE = NCEP_ROOT + "Gempak"+File.separator+"gempakMarkerType.tbl"; - - // Note: These are read by Raytheon's code which just takes the directory as input and - // assumes the filename. So don't change the fileNames. - // the files. - public static final String RADAR_INFO = NCEP_ROOT + "Radar"+File.separator+"radarInfo.txt"; -// public static final String MOSAIC_INFO = NCEP_ROOT + "Radar"+File.separator+"mosaicInfo.txt"; - public static final String MCIDAS_IMG_STYLE_RULES = STYLE_RULES_DIR + "mcidasSatelliteImageryStyleRules.xml"; - public static final String GINI_IMG_STYLE_RULES = STYLE_RULES_DIR + "giniSatelliteImageryStyleRules.xml"; - public static final String SOLAR_IMG_STYLE_RULES = STYLE_RULES_DIR + "solarImageryStyleRules.xml"; - // PGEN Files - public static final String PGEN_ROOT = NCEP_ROOT + "pgen"+File.separator; - public static final String PGEN_SETTINGS_TBL = PGEN_ROOT + "settings_tbl.xml"; - public static final String PGEN_LINE_PATTERNS = PGEN_ROOT + "linePatterns.xml"; - public static final String PGEN_SYMBOL_PATTERNS = PGEN_ROOT + "symbolPatterns.xml"; - public static final String PGEN_PRODUCT_TYPES = PGEN_ROOT + "productTypes.xml"; - public static final String PGEN_HELP_FILE = PGEN_ROOT + "PgenHelp.txt"; - public static final String PGEN_TCA_ATTR_INFO = PGEN_ROOT + "TCAinfo.xml"; - public static final String PGEN_GFA_ATTR_FILE = PGEN_ROOT + "gfa.xml"; - public static final String PGEN_GFA_PROD_XSL = PGEN_ROOT + "xslt"+File.separator+ - "airmet"+File.separator+"gfa_product.xsl"; - public static final String PGEN_AIRMET_CYCLE_TBL= PGEN_ROOT + "airmetcycle.xml"; - public static final String PGEN_ISLND_BRKPTS_TBL= PGEN_ROOT + "IslandBreakpoints.xml"; - public static final String PGEN_WATER_BRKPTS_TBL= PGEN_ROOT + "WaterBreakpoints.xml"; - public static final String PGEN_COAST_BRKPTS_TBL= PGEN_ROOT + "CoastBreakpoints.xml"; - public static final String PGEN_SPC_ANCHOR_TBL = SPCWATCH_STN_TBL; - public static final String PGEN_FIR_BOUNDS = SHAPEFILES_DIR +File.separator+ "firbnds"+File.separator+"firbnds.shp"; - public static final String PGEN_CCFP_TIMES = PGEN_ROOT + "ccfpTimes.xml"; - public static final String PGEN_CCFP_XSLT = PGEN_ROOT + "xslt"+File.separator+ - "ccfp"+File.separator+"ccfpXml2Txt.xslt"; - public static final String PGEN_VAA_FILE = PGEN_ROOT + "vaa.xml"; - public static final String PGEN_VAA_XSLT = PGEN_ROOT + "xslt"+File.separator+ - "vaa"+File.separator+"vaaXml2Txt.xslt"; - public static final String PGEN_PHENOMENONS = PGEN_ROOT + "phenomenons.xml"; - - // - public static final String PGEN_PROD_SCHEMA = PGEN_ROOT + "product.xsd"; - public static final String PGEN_RED_CROSS_IMG = PGEN_ROOT + "red_cross.png"; - public static final String PGEN_OUTLOOK_TYPE = PGEN_ROOT + "outlooktype.xml"; - public static final String PGEN_OUTLOOK_SETTINGS= PGEN_ROOT + "outlooksettings.xml"; - public static final String PGEN_OUTLOOK_TIMES = PGEN_ROOT + "outlooktimes.xml"; - public static final String PGEN_MNTN_OBSC_STATES= PGEN_ROOT + "mt_obsc_states.xml"; - public static final String PGEN_CONTOURS_INFO = PGEN_ROOT + "contoursInfo.xml"; - public static final String PGEN_G2G_GRPHGD = PGEN_ROOT + "grphgd.tbl"; - public static final String PGEN_FILTER_HOUR = PGEN_ROOT + "filterHour.xml"; - public static final String PGEN_FORECASTER = PGEN_ROOT + "forecasters.xml"; - - public static final String NSHARP_NLIST_FILE = NCEP_ROOT + "nsharp"+File.separator+"nlist.txt"; - public static final String NSHARP_SUP_FILE = NCEP_ROOT + "nsharp"+File.separator+"sup.txt"; - //nsharp configuration - public static final String NSHARP_CONFIG = NCEP_ROOT + "nsharp"+ File.separator+"nsharpConfig.xml"; + public static final String RSC_DEFNS_DIR = NCEP_ROOT + "ResourceDefns"; - } - - public static synchronized NcPathManager getInstance() { - if( ncPathMngr == null ) { - ncPathMngr = new NcPathManager(); - } - return ncPathMngr; - } - - private NcPathManager() { - - // Uses the same CAVELocalizationAdapter. - pathMngr = PathManagerFactory.getPathManager( new CAVELocalizationAdapter() ); - - } - - public void createDeskLevelLocalization( String deskName ) { - // SITE < DESK < USER - - // NOTE : order of 650 is between SITE(order=500) and USER(order=1000). - LocalizationLevel DESK = LocalizationLevel.createLevel( - NcPathConstants.DESK_LEVEL, 650 ); + public static final String ATTR_SET_GROUPS_DIR = NCEP_ROOT + + "AttributeSetGroups"; - // sanity check to make sure the order is correct - // - if( LocalizationLevel.SITE.compareTo( DESK ) >= 0 ) { - System.out.println("WARNING: the SITE level order >= the DESK???? "); - } - if( LocalizationLevel.USER.compareTo( DESK ) <= 0 ) { - System.out.println("WARNING: the USER level order <= the DESK???? "); - } + public static final String PREDEFINED_AREAS_DIR = NCEP_ROOT + + "PredefinedAreas"; - LocalizationManager.getInstance(); + public static final String COLORBARS_DIR = NCEP_ROOT + "ColorBars"; - LocalizationManager.registerContextName( DESK, deskName ); - } - - public LocalizationLevel getDeskLevel() { - return LocalizationLevel.valueOf( NcPathConstants.DESK_LEVEL ); - } - - public LocalizationContext getDeskContext() { - return getContext( LocalizationType.CAVE_STATIC, getDeskLevel() ); - } + public static final String COLORMAPS_DIR = NCEP_ROOT + "ColorMaps"; - // same thing as calling PathManagerFactory.getPathManager(); - public IPathManager getPathManager() { - return pathMngr; - } - - // Use this method if we don't care or need to know which context the file comes from. - public File getStaticFile( String fname ) { - return pathMngr.getStaticFile( fname ); - } + public static final String STATIONS_DIR = NCEP_ROOT + "Stations"; + + public static final String LOGOS_DIR = NCEP_ROOT + "Logos"; + + public static final String CURSORS_DIR = NCEP_ROOT + "Cursors"; + + public static final String PLOT_MODELS_DIR = NCEP_ROOT + "PlotModels"; + + public static final String PLOT_PARAMETERS_DIR = PLOT_MODELS_DIR + + File.separator + "PlotParameters"; + + public static final String FONT_FILES_DIR = NCEP_ROOT + "fontFiles" + + File.separator; + + public static final String LOCATOR_SOURCE_DIR = NCEP_ROOT + + "LocatorDataSources"; + + public static final String RESOURCE_FILTERS = RSC_DEFNS_DIR + + File.separator + "ResourceFilters.xml"; + + public static final String AREA_MENUS_FILE = PREDEFINED_AREAS_DIR + + File.separator + "menus" + File.separator + "AreaMenus.xml"; + + // No longer used. location is now a parameter for the + // StaticPgenOverlayResource. + // public static final String PGEN_XML_OVERLAYS = NCEP_ROOT + + // "StaticPgenOverlays"; + public static final String STYLE_RULES_DIR = NCEP_ROOT + "styleRules" + + File.separator; + + // lpi,spi files for overlays + public static final String BASEMAPS_DIR = NCEP_ROOT + "basemaps"; + + // static files + public static final String DFLT_RBD = NCEP_ROOT + "DefaultRBDs" + + File.separator + "defaultRBD.xml"; + + public static final String DFLT_NTRANS_RBD = NCEP_ROOT + "DefaultRBDs" + + File.separator + "defaultNTransRBD.xml"; + + public static final String DFLT_SOLAR_RBD = NCEP_ROOT + "DefaultRBDs" + + File.separator + "defaultSolarRBD.xml"; + + public static final String DFLT_GRAPH_RBD = NCEP_ROOT + "DefaultRBDs" + + File.separator + "defaultGraphRBD.xml"; + + public static final String LOCATOR_TBL = NCEP_ROOT + "Locator" + + File.separator + "locator_tbl.xml"; + + public static final String LOGOS_TBL = NCEP_ROOT + "Logos" + + File.separator + "logos.tbl"; + + public static final String LOOP_SPEEDS_TBL = NCEP_ROOT + "LoopControls" + + File.separator + "loopSpeeds.tbl"; + + public static final String LOCKED_CMAP_TBL = NcPathConstants.COLORMAPS_DIR + + File.separator + "lockedColorMaps.tbl"; + + public static final String CURSOR_REFS_TBL = CURSORS_DIR + + File.separator + "cursorref_tbl.xml"; + + public static final String CLOUD_HEIGHT_SOUNDING_MODELS = NCEP_ROOT + + "CloudHeight" + File.separator + "SoundingModels.xml"; + + public static final String GEOG_TBL = PREDEFINED_AREAS_DIR + + File.separator + "gempak" + File.separator + "geog.xml"; + + public static final String SFSTNS_TBL = STATIONS_DIR + File.separator + + "sfstns.xml"; + + public static final String CONDITIONAL_FILTERS_DIR = PLOT_MODELS_DIR + + File.separator + "ConditionalFilters"; + + public static final String CONDITIONAL_FILTER_HELP_FILE = NCEP_ROOT + + File.separator + "conditionalFilter" + File.separator + + "ConditionalFilterHelp.txt"; + + public static final String CONDITIONAL_FILTER_MINUS_IMG = NCEP_ROOT + + File.separator + "conditionalFilter" + File.separator + + "minus_red.gif"; + + public static final String CONDITIONAL_FILTER_PLUS_IMG = NCEP_ROOT + + File.separator + "conditionalFilter" + File.separator + + "plus_green.gif"; + + public static final String ADVANCED_ICON_IMG = NCEP_ROOT + + File.separator + "advanced" + File.separator + "adv_icon.jpg"; + + // migrating code which looked for these filenames + public static final String VORS_STN_TBL = STATIONS_DIR + File.separator + + "vors.xml"; + + public static final String VOLCANO_STN_TBL = STATIONS_DIR + + File.separator + "volcano.xml"; + + public static final String COUNTY_STN_TBL = STATIONS_DIR + + File.separator + "county.xml"; + + public static final String FFG_ZONES_STN_TBL = STATIONS_DIR + + File.separator + "ffgZones.xml"; + + public static final String SPCWATCH_STN_TBL = STATIONS_DIR + + File.separator + "spcwatch.xml"; + + public static final String SHAPEFILES_DIR = NCEP_ROOT + "Shapefiles"; + + public static final String SEEK_STN_TBL = NCEP_ROOT + "Seek" + + File.separator + "seekStns.xml"; + + // public static final String GRID_DATATYPE_TBL = NCEP_ROOT + + // "grid"+File.separator+"datatype.tbl"; + // public static final String ENSEMBLE_MODELS_TBL= NCEP_ROOT + + // "grid"+File.separator+"ensemble_models.tbl"; + public static final String GEMPAK_MARKER_TYPE = NCEP_ROOT + "Gempak" + + File.separator + "gempakMarkerType.tbl"; + + // Note: These are read by Raytheon's code which just takes the + // directory as input and + // assumes the filename. So don't change the fileNames. + // the files. + public static final String RADAR_INFO = NCEP_ROOT + "Radar" + + File.separator + "radarInfo.txt"; + + // public static final String MOSAIC_INFO = NCEP_ROOT + + // "Radar"+File.separator+"mosaicInfo.txt"; + public static final String MCIDAS_IMG_STYLE_RULES = STYLE_RULES_DIR + + "mcidasSatelliteImageryStyleRules.xml"; + + public static final String GINI_IMG_STYLE_RULES = STYLE_RULES_DIR + + "giniSatelliteImageryStyleRules.xml"; + + public static final String SOLAR_IMG_STYLE_RULES = STYLE_RULES_DIR + + "solarImageryStyleRules.xml"; + + // PGEN Files + public static final String PGEN_ROOT = NCEP_ROOT + "pgen" + + File.separator; + + public static final String PGEN_SETTINGS_TBL = PGEN_ROOT + + "settings_tbl.xml"; + + public static final String PGEN_LINE_PATTERNS = PGEN_ROOT + + "linePatterns.xml"; + + public static final String PGEN_SYMBOL_PATTERNS = PGEN_ROOT + + "symbolPatterns.xml"; + + public static final String PGEN_PRODUCT_TYPES = PGEN_ROOT + + "productTypes.xml"; + + public static final String PGEN_HELP_FILE = PGEN_ROOT + "PgenHelp.txt"; + + public static final String PGEN_TCA_ATTR_INFO = PGEN_ROOT + + "TCAinfo.xml"; + + public static final String PGEN_GFA_ATTR_FILE = PGEN_ROOT + "gfa.xml"; + + public static final String PGEN_GFA_PROD_XSL = PGEN_ROOT + "xslt" + + File.separator + "airmet" + File.separator + + "gfa_product.xsl"; + + public static final String PGEN_AIRMET_CYCLE_TBL = PGEN_ROOT + + "airmetcycle.xml"; + + public static final String PGEN_ISLND_BRKPTS_TBL = PGEN_ROOT + + "IslandBreakpoints.xml"; + + public static final String PGEN_WATER_BRKPTS_TBL = PGEN_ROOT + + "WaterBreakpoints.xml"; + + public static final String PGEN_COAST_BRKPTS_TBL = PGEN_ROOT + + "CoastBreakpoints.xml"; + + public static final String PGEN_SPC_ANCHOR_TBL = SPCWATCH_STN_TBL; + + public static final String PGEN_FIR_BOUNDS = SHAPEFILES_DIR + + File.separator + "firbnds" + File.separator + "firbnds.shp"; + + public static final String PGEN_CCFP_TIMES = PGEN_ROOT + + "ccfpTimes.xml"; + + public static final String PGEN_CCFP_XSLT = PGEN_ROOT + "xslt" + + File.separator + "ccfp" + File.separator + "ccfpXml2Txt.xslt"; + + public static final String PGEN_VAA_FILE = PGEN_ROOT + "vaa.xml"; + + public static final String PGEN_VAA_XSLT = PGEN_ROOT + "xslt" + + File.separator + "vaa" + File.separator + "vaaXml2Txt.xslt"; + + public static final String PGEN_PHENOMENONS = PGEN_ROOT + + "phenomenons.xml"; + + // + public static final String PGEN_PROD_SCHEMA = PGEN_ROOT + "product.xsd"; + + public static final String PGEN_RED_CROSS_IMG = PGEN_ROOT + + "red_cross.png"; + + public static final String PGEN_OUTLOOK_TYPE = PGEN_ROOT + + "outlooktype.xml"; + + public static final String PGEN_OUTLOOK_SETTINGS = PGEN_ROOT + + "outlooksettings.xml"; + + public static final String PGEN_OUTLOOK_TIMES = PGEN_ROOT + + "outlooktimes.xml"; + + public static final String PGEN_MNTN_OBSC_STATES = PGEN_ROOT + + "mt_obsc_states.xml"; + + public static final String PGEN_CONTOURS_INFO = PGEN_ROOT + + "contoursInfo.xml"; + + public static final String PGEN_G2G_GRPHGD = PGEN_ROOT + "grphgd.tbl"; + + public static final String PGEN_FILTER_HOUR = PGEN_ROOT + + "filterHour.xml"; + + public static final String PGEN_FORECASTER = PGEN_ROOT + + "forecasters.xml"; + + public static final String NSHARP_NLIST_FILE = NCEP_ROOT + "nsharp" + + File.separator + "nlist.txt"; + + public static final String NSHARP_SUP_FILE = NCEP_ROOT + "nsharp" + + File.separator + "sup.txt"; + + // nsharp configuration + public static final String NSHARP_CONFIG = NCEP_ROOT + "nsharp" + + File.separator + "nsharpConfig.xml"; - // Use this method if we don't care which context the file comes from but we - // need to know which one it was from. - // - public LocalizationFile getStaticLocalizationFile( String name ) { - return pathMngr.getStaticLocalizationFile( name ); - } - - // This can be used to create a new LocalizationFile. - // - public LocalizationFile getLocalizationFile( LocalizationContext context, - String name) { - return pathMngr.getLocalizationFile( context, name); } - - // only include 1 version of each filename. Assume CAVE_STATIC (can change this later) - // - public Map listFiles( - String name, String[] filter, boolean recursive, boolean filesOnly ) { - LocalizationContext[] contexts = getLocalSearchHierarchy( LocalizationType.CAVE_STATIC ); - - return listFiles( contexts, name, filter, recursive, filesOnly ); + + public static synchronized NcPathManager getInstance() { + if (ncPathMngr == null) { + ncPathMngr = new NcPathManager(); + } + return ncPathMngr; + } + + private NcPathManager() { + + // Uses the same CAVELocalizationAdapter. + pathMngr = PathManagerFactory + .getPathManager(new CAVELocalizationAdapter()); + + } + + public void createDeskLevelLocalization(String deskName) { + // SITE < DESK < USER + + // NOTE : order of 650 is between SITE(order=500) and USER(order=1000). + LocalizationLevel DESK = LocalizationLevel.createLevel( + NcPathConstants.DESK_LEVEL, 650); + + // sanity check to make sure the order is correct + // + if (LocalizationLevel.SITE.compareTo(DESK) >= 0) { + System.out + .println("WARNING: the SITE level order >= the DESK???? "); + } + if (LocalizationLevel.USER.compareTo(DESK) <= 0) { + System.out + .println("WARNING: the USER level order <= the DESK???? "); + } + + LocalizationManager.getInstance(); + + LocalizationManager.registerContextName(DESK, deskName); + } + + public LocalizationLevel getDeskLevel() { + return LocalizationLevel.valueOf(NcPathConstants.DESK_LEVEL); + } + + public LocalizationContext getDeskContext() { + return getContext(LocalizationType.CAVE_STATIC, getDeskLevel()); + } + + // same thing as calling PathManagerFactory.getPathManager(); + public IPathManager getPathManager() { + return pathMngr; + } + + // Use this method if we don't care or need to know which context the file + // comes from. + public File getStaticFile(String fname) { + return pathMngr.getStaticFile(fname); + } + + // Use this method if we don't care which context the file comes from but we + // need to know which one it was from. + // + public LocalizationFile getStaticLocalizationFile(String name) { + return pathMngr.getStaticLocalizationFile(name); + } + + // This can be used to create a new LocalizationFile. + // + public LocalizationFile getLocalizationFile(LocalizationContext context, + String name) { + return pathMngr.getLocalizationFile(context, name); + } + + // only include 1 version of each filename. Assume CAVE_STATIC (can change + // this later) + // + public Map listFiles(String name, + String[] filter, boolean recursive, boolean filesOnly) { + LocalizationContext[] contexts = getLocalSearchHierarchy(LocalizationType.CAVE_STATIC); + + return listFiles(contexts, name, filter, recursive, filesOnly); } // created to allow listFiles for COMMON_STATIC contexts // - public Map listFiles( LocalizationContext[] contexts, - String name, String[] filter, boolean recursive, boolean filesOnly ) { - + public Map listFiles( + LocalizationContext[] contexts, String name, String[] filter, + boolean recursive, boolean filesOnly) { + Map lFileMap = new HashMap(); - List lFilesList = - Arrays.asList( - pathMngr.listFiles( contexts, name, filter, recursive, filesOnly ) ); + List lFilesList = Arrays.asList(pathMngr.listFiles( + contexts, name, filter, recursive, filesOnly)); - // loop thru the files and add them to the map if there is not already a file - // present from a higher level. - // - for( LocalizationFile lFile : lFilesList ) { - String lName = lFile.getName(); - LocalizationLevel lLvl = lFile.getContext().getLocalizationLevel(); - - if( !lFileMap.containsKey( lName ) || - (lFileMap.get( lName ).getContext().getLocalizationLevel().compareTo( lLvl ) < 0) ) { - //System.out.println("listFiles "+lFile.getFile().getAbsolutePath()); - lFileMap.put( lFile.getName(), lFile ); - } - - } - - return lFileMap; - } + // loop thru the files and add them to the map if there is not already a + // file + // present from a higher level. + // + for (LocalizationFile lFile : lFilesList) { + String lName = lFile.getName(); + LocalizationLevel lLvl = lFile.getContext().getLocalizationLevel(); + + if (!lFileMap.containsKey(lName) + || (lFileMap.get(lName).getContext().getLocalizationLevel() + .compareTo(lLvl) < 0)) { + // System.out.println("listFiles "+lFile.getFile().getAbsolutePath()); + lFileMap.put(lFile.getName(), lFile); + } + + } + + return lFileMap; + } // convienence method to get all the versions of a file. Assume CAVE_STATIC. - public Map getTieredLocalizationFile( String name) { - return pathMngr.getTieredLocalizationFile( LocalizationType.CAVE_STATIC, name ); - } - - public LocalizationContext getContext( LocalizationType type, + public Map getTieredLocalizationFile( + String name) { + return pathMngr.getTieredLocalizationFile(LocalizationType.CAVE_STATIC, + name); + } + + public LocalizationContext getContext(LocalizationType type, LocalizationLevel level) { return pathMngr.getContext(type, level); } public String[] getContextList(LocalizationLevel level) { - return pathMngr.getContextList(level); + return pathMngr.getContextList(level); } - + public LocalizationContext[] getLocalSearchHierarchy(LocalizationType type) { - return pathMngr.getLocalSearchHierarchy( type ); + return pathMngr.getLocalSearchHierarchy(type); } // return a map of all files from all contexts // this would make it easier to 'revert' files - // -// public Map listFilesFromAllContexts( -// // getTieredLocalizationFile( -// // LocalizationType type, -// String name, String[] filter, boolean recursive, boolean filesOnly ) { -// Map map = new HashMap(); -// -// for( LocalizationLevel level : ncLevels ) { -// LocalizationContext context = getContext( LocalizationType.CAVE_STATIC, level ); -// -// LocalizationFile[] lFiles = -// pathMngr.listFiles( getLocalSearchHierarchy( LocalizationType.CAVE_STATIC ), -// name, filter, recursive, filesOnly ); -//// LocalizationFile lf = getLocalizationFile( context, name ); -// -// if( lf.exists() ) { -// map.put(, lf); -// } -// } -// -// return map; -// } + // + // public Map listFilesFromAllContexts( + // // getTieredLocalizationFile( + // // LocalizationType type, + // String name, String[] filter, boolean recursive, boolean filesOnly ) { + // Map map = new HashMap(); + // + // for( LocalizationLevel level : ncLevels ) { + // LocalizationContext context = getContext( LocalizationType.CAVE_STATIC, + // level ); + // + // LocalizationFile[] lFiles = + // pathMngr.listFiles( getLocalSearchHierarchy( LocalizationType.CAVE_STATIC + // ), + // name, filter, recursive, filesOnly ); + // // LocalizationFile lf = getLocalizationFile( context, name ); + // + // if( lf.exists() ) { + // map.put(, lf); + // } + // } + // + // return map; + // } - // delete the file and also return a superceding file if one exists. - // -// public LocalizationFile revert( File file, LocalizationContext context, String fileName, boolean findReplacement ) -// throws LocalizationOpFailedException { -// super.delete(file, context, fileName); -// -// if( findReplacement ) { -//// LocalizationContext superContext = new LocalizationContext( -//// context.getLocalizationType(), -//// LocalizationManager.getInstance().get -// } -// -// return null; -// } + // + // public LocalizationFile revert( File file, LocalizationContext context, + // String fileName, boolean findReplacement ) + // throws LocalizationOpFailedException { + // super.delete(file, context, fileName); + // + // if( findReplacement ) { + // // LocalizationContext superContext = new LocalizationContext( + // // context.getLocalizationType(), + // // LocalizationManager.getInstance().get + // } + // + // return null; + // } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.resourceManager/META-INF/MANIFEST.MF index b73e56d173..183c0e9b3e 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/META-INF/MANIFEST.MF @@ -27,4 +27,5 @@ Export-Package: gov.noaa.nws.ncep.viz.resourceManager, gov.noaa.nws.ncep.viz.resourceManager.ui.createRbd, gov.noaa.nws.ncep.viz.resourceManager.ui.loadRbd, gov.noaa.nws.ncep.viz.resourceManager.ui.manageResources -Import-Package: gov.noaa.nws.ncep.viz.rsc.pgen +Import-Package: gov.noaa.nws.ncep.viz.resourceManager.timeline, + gov.noaa.nws.ncep.viz.rsc.pgen diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java new file mode 100644 index 0000000000..4fe373da13 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/GraphTimelineControl.java @@ -0,0 +1,2047 @@ +/* + * Timeline + * + * Date created 03 MARCH 2010 + * + * This code has been developed by the SIB for use in the AWIPS2 system. + */ + +package gov.noaa.nws.ncep.viz.resourceManager.timeline; + +import gov.noaa.nws.ncep.viz.common.ui.CalendarSelectDialog; +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData.TimelineGenMethod; +import gov.noaa.nws.ncep.viz.resources.time_match.GraphTimelineUtil; +import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Spinner; + +import com.raytheon.uf.common.time.DataTime; + +/** + * This class is an override on the TimelineControl for display graph time line. + * The main difference are removing numFrames, and numSkip, and adding + * graphRange and hourSnap. + * + * For non-graph, we have many frames and each data is in a frame. But for + * graph, we only have one frame and many data in the frame. + * + * The numFrames and frameTimes are basic criteria for timeline control. we + * change a concept here. We put data in frameTimes, so the timeline and + * timeMatcher classes still work, but there is only one frame, not "frameTimes" + * frames. + * + * Timeline: A graphical view of available data times, that allows users to + * select any or all data times from the available list. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 04/28/2014     #1131     qzhou       Initial (removed numFrames, numSkip, added graphRange, hourSnap)
+ * 05/14/2014     #1131     qzhou       Add snapAvailtimes to append data at the end to fill the snap period.
+ *                                      Change MourseUp function to handle snap.
+ *                                      Add functions to get position from time and vice versa
+ *                                      Modified updateTimeline, updateSelectedTimes, calculateSlider, calculateAvailableBoxes
+ * 06/10/2014     #1136     qzhou       Modified getSelectedTimes and updateTimeline
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ +public class GraphTimelineControl extends TimelineControl { + + private final String[] noResourcesList = { " None Available " }; + + private final String manualTimelineStr = " Manual Timeline "; + + // private HashMap> availDomResourcesMap + // = null; + + // private AbstractNatlCntrsRequestableResourceData domRscData = null; + + // private Combo dom_rsc_combo = null; + + // private NCTimeMatcher timeMatcher = null; + + // public interface IDominantResourceChangedListener { + // public void dominantResourceChanged( + // AbstractNatlCntrsRequestableResourceData newDomRsc); + // } + // + // private Set + // dominantResourceChangedListeners = new + // HashSet(); + + private enum MODE { + MOVE_LEFT, MOVE_RIGHT, MOVE_ALL + }; + + private final float DATE_LINE = 0.25f; + + private final float TIME_LINE = 0.60f; + + private final int MARGIN = 15; + + private final int MARKER_WIDTH = 5; + + private final int MARKER_HEIGHT = 10; + + private final int SLIDER = 10; + + private final int TICK_SMALL = 5; + + private final int TICK_LARGE = 7; + + private final int MAX_DATES = 10; + + // if this is not null then the message is displayed in place of + // a timeline. This should only be set when no times are available. + private String timelineStateMessage = null; + + private Canvas canvas; + + private Combo graphRangeCombo; + + private Combo hourSnapCombo; + + private Spinner timeRangeDaysSpnr; + + private Spinner timeRangeHrsSpnr; + + private Combo frameIntervalCombo; + + private Combo refTimeCombo; + + private Label refTimeLbl; + + private int timeRangeHrs = 0; // + + private String availFrameIntervalStrings[] = { "Data", "1 min", "2 mins", + "5 mins", "10 mins", "15 mins", "20 mins", "30 mins", "1 hr", + "90 mins", "2 hrs", "3 hrs", "6 hrs", "12 hrs", "24 hrs" }; + + private int availFrameIntervalMins[] = { -1, 1, 2, 5, 10, 15, 20, 30, 60, + 90, 120, 180, 360, 720, 1440 }; + + private String availGraphRangeStrings[] = { "3 hrs", "6 hrs", "12 hrs", + "24 hrs", "3 days", "7 days" }; + + private int availGraphRangeHrs[] = { 3, 6, 12, 24, 72, 168 }; + + // extend refTime to next snap point + private String availHourSnapStrings[] = { "0", "1", "3", "6", "12", "24" }; + + private int availHourSnapHrs[] = { 0, 1, 3, 6, 12, 24 }; + + // keep this in order since code is referencing the index into this list. + private String refTimeSelectionOptions[] = { "Current", "Latest ", + "Calendar ..." }; + + private Font canvasFont; + + private Cursor pointerCursor; + + private Cursor resizeCursor; + + private Cursor grabCursor; + + private Rectangle slider = null; + + private int sliderMin, sliderMax; + + // private TimelineData timeData; + + private Map availableTimes; + + private Map timeLocations; + + private boolean hasDifferentMinutes = false; + + private List days; + + private List dayLocation; + + private Color canvasColor, availableColor, selectedColor; + + private Shell shell; + + private int newGraphRange = 0; + + public GraphTimelineControl(Composite parent) { + + super(parent, "Graph"); + shell = parent.getShell(); + + // timeMatcher = new NCTimeMatcher(); + availDomResourcesMap = new HashMap>(); + + Composite top_form = this; + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + gd.verticalAlignment = SWT.FILL; + top_form.setLayoutData(gd); + + top_form.setLayout(new FormLayout()); + + dom_rsc_combo = new Combo(top_form, SWT.DROP_DOWN | SWT.READ_ONLY); + FormData fd = new FormData(); + fd.width = 330; + fd.top = new FormAttachment(0, 0); + fd.left = new FormAttachment(30, 0); + + dom_rsc_combo.setLayoutData(fd); + + Label dom_rsc_lbl = new Label(top_form, SWT.NONE); + dom_rsc_lbl.setText("Dominant Resource"); + fd = new FormData(); + fd.top = new FormAttachment(dom_rsc_combo, 2, SWT.TOP); + fd.right = new FormAttachment(dom_rsc_combo, -10, SWT.LEFT); + dom_rsc_lbl.setLayoutData(fd); + + // if changing the dominant resource then change the timeline + dom_rsc_combo.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + + selectDominantResource(); + } + }); + + dom_rsc_combo.setItems(noResourcesList); + dom_rsc_combo.select(0); + + canvasColor = new Color(getDisplay(), 255, 255, 255); + availableColor = new Color(getDisplay(), 0, 0, 255); + selectedColor = new Color(getDisplay(), 255, 0, 0); + canvasFont = new Font(getDisplay(), "Times", 11, SWT.BOLD); + pointerCursor = new Cursor(getDisplay(), SWT.CURSOR_ARROW); + resizeCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEW); + grabCursor = new Cursor(getDisplay(), SWT.CURSOR_HAND); + + createWidgets(top_form); + + addSpinnerListeners(); + + updateTimeline(new NCTimeMatcher()); + } + + public void addDominantResourceChangedListener( + IDominantResourceChangedListener lstnr) { + dominantResourceChangedListeners.add(lstnr); + } + + public boolean removeAddDominantResourceChangedListener( + IDominantResourceChangedListener lstnr) { + return dominantResourceChangedListeners.remove(lstnr); + } + + // set the timeMatcher and update the widgets for it. + public boolean setTimeMatcher(NCTimeMatcher tm) { + // this can happen if the user brings up the RBD Manager (usually with + // the spacebar) before there is an editor with a timeline + if (tm == null) { + timeMatcher = new NCTimeMatcher(); + return false; + } + + timeMatcher = tm; + + timeMatcher.loadTimes(false); + + if (timeMatcher.getDominantResourceName() != null) { + for (int i = 0; i < dom_rsc_combo.getItemCount(); i++) { + if (dom_rsc_combo.getItem(i).equals( + timeMatcher.getDominantResourceName().toString())) { + dom_rsc_combo.select(i); + } + } + } else { + dom_rsc_combo.select(0); // 'None Available" + } + + updateTimeline(timeMatcher); + + // set the domRscData from the combo and + if (getDominantResource() == null) { + return false; + } + + return true; + } + + public NCTimeMatcher getTimeMatcher() { + timeMatcher.setFrameTimes(toDataTimes(getSelectedTimes())); + return timeMatcher; + } + + private ArrayList toDataTimes(List times) { + ArrayList dlist = new ArrayList(); + for (Calendar cal : times) { + DataTime dtime = new DataTime(cal); + dlist.add(dtime); + } + return dlist; + } + + // set domRscData from the combo selection + public AbstractNatlCntrsRequestableResourceData getDominantResource() { + // look up this resource in the map of stored avail + // dominant resources and use the first in the list + // as the dominant resource. + String seldRscName = dom_rsc_combo.getText(); + + if (seldRscName.equals(noResourcesList[0])) { + domRscData = null; + return domRscData; + } + // if nothing is selected then return null. + else if (seldRscName.isEmpty()) { + domRscData = null; + return domRscData; + } else { + ArrayList seldRscsList = availDomResourcesMap + .get(seldRscName.toString()); + + if (seldRscsList == null || seldRscsList.isEmpty()) { + System.out.println("Sanity Check: seld Rsc " + seldRscName + + " not found."); + domRscData = null; + return domRscData; + } + + // TODO : There is a small hole in the design here in the case where + // Manual Timeline is selected for the event type resources and + // there are + // more than one event resource available. The dominant will be the + // first + // in the list. But the since the user will need to manually select + // a frame + // interval the only real problem is that the latest data will + // reference + // this resource. If the user needed the latest data of the second + // or other + // event resource then they wouldn't be able to unless they removed + // the + // resources and re-selected in a new order. + // + domRscData = seldRscsList.get(0); + return domRscData; + } + } + + public void selectManualTimeline() { + + } + + // set this dominant Resource in the combo and select it as the dominant + // + public boolean setDominantResource( + AbstractNatlCntrsRequestableResourceData domRsc) { + // loop thru the combo items + for (String comboEntry : dom_rsc_combo.getItems()) { + if (!comboEntry.equals(noResourcesList[0])) { + if (comboEntry.equals(manualTimelineStr)) { + } + + String mapKey = comboEntry; + ArrayList seldRscsList = availDomResourcesMap + .get(mapKey); + + if (seldRscsList == null || seldRscsList.isEmpty()) { + domRscData = null; + return false; + } + for (AbstractNatlCntrsRequestableResourceData rsc : seldRscsList) { + if (rsc.getResourceName().equals(domRsc.getResourceName())) { + domRscData = domRsc; + dom_rsc_combo.setText(comboEntry); + break; + } + } + } + } + + selectDominantResource(); + + return true; + } + + // set the numFrames from the domRsc to the timeMatcher. + public void selectDominantResource() { + + // get the dominant resource from the selected combo item + // and set it in the timeMatcher. + if (getDominantResource() == null) { + timeMatcher.setDominantResourceData(null); + } else { + timeMatcher.setDominantResourceData(domRscData); + } + + timeMatcher.updateFromDominantResource(); + + updateTimeline(timeMatcher); + + // call all the listeners (used to set the auto update button) + for (IDominantResourceChangedListener lstnr : dominantResourceChangedListeners) { + lstnr.dominantResourceChanged(domRscData); + } + } + + public void addAvailDomResource(AbstractNatlCntrsRequestableResourceData rsc) { + + String mapKey; // the key for the map and the entry in the combo box + + // for 'event' resources which requires a manual timeline then + // add "Manual" as a selection option + // + if (rsc.getTimelineGenMethod() == TimelineGenMethod.USE_MANUAL_TIMELINE) { + mapKey = manualTimelineStr; + } else { + mapKey = rsc.getResourceName().toString(); + } + + ArrayList rscList = availDomResourcesMap + .get(mapKey); + + // if no resource by this name then create an + // entry in the map. + if (rscList == null) { + rscList = new ArrayList(); + availDomResourcesMap.put(mapKey, rscList); + } + + // If there is no entry in the map then add the resource and update the + // combo + if (rscList.isEmpty()) { + rscList.add(rsc); + + dom_rsc_combo.add(mapKey); + + // remove none from the list + if (dom_rsc_combo.getItem(0).equals(noResourcesList[0])) { + if (dom_rsc_combo.getSelectionIndex() == 0) { + dom_rsc_combo.remove(0); + + dom_rsc_combo.deselectAll(); + domRscData = null; + // dom_rsc_combo.select(0); + // selectDominantResource(); + } else { + dom_rsc_combo.remove(0); + } + } + } else { + // otherwise there are already other resources with the same name so + // just + // add this one. (We need to do this in case one of the other + // resources is + // removed then this one still needs to be made available as a + // dominant resource) + rscList.add(rsc); + } + } + + // TODO : implement ; this is complicated by the fact that there may be + // another + // resource in another pane to 'replace' this one so we will need to save + // all + // the possible resources and only present the unique ones to the user. + // + public boolean removeAvailDomResource( + AbstractNatlCntrsRequestableResourceData rsc) { + + String mapKey; + + if (rsc.getTimelineGenMethod() == TimelineGenMethod.USE_MANUAL_TIMELINE) { + mapKey = manualTimelineStr; + } else { + mapKey = rsc.getResourceName().toString(); + } + + ArrayList rscList = availDomResourcesMap + .get(mapKey); + + if (rscList == null || rscList.isEmpty()) { + System.out.println("removeAvailDomResource: " + mapKey + + " is not in the availDomResourcesMap??"); + return false; + } + + rscList.remove(rsc); + + // if this was the last resource with this name in the list and if it is + // currently selected + // then change the dominant resource. + if (rscList.isEmpty()) { + + // if currently selected, + if (dom_rsc_combo.getText().equals(mapKey)) { + + dom_rsc_combo.remove(mapKey); + + if (dom_rsc_combo.getItemCount() == 0) { + dom_rsc_combo.setItems(noResourcesList); + } + + dom_rsc_combo.select(0); + selectDominantResource(); + } else { + dom_rsc_combo.remove(mapKey); + } + } + // if this is an event type then force the next event type resource to + // be the + // dominant. + else if (rsc.getTimelineGenMethod() == TimelineGenMethod.USE_MANUAL_TIMELINE) { + selectDominantResource(); + } + + return true; + } + + public void clearTimeline() { + availDomResourcesMap.clear(); + dom_rsc_combo.setItems(noResourcesList); + dom_rsc_combo.select(0); + + setTimeMatcher(new NCTimeMatcher()); + updateTimeline(timeMatcher); + } + + // End of methods from old TimelineControl + + // Methods from old Timeline class + public void setTimelineState(String state, boolean disable) { + + timelineStateMessage = state; + + setControlsEnabled(!disable); + canvas.redraw(); + } + + public void updateTimeline(NCTimeMatcher tm) { + timeMatcher = tm; + + if (timeMatcher.isCurrentRefTime()) { + refTimeCombo.select(0); + } else if (timeMatcher.isLatestRefTime()) { + refTimeCombo.select(1); + } else { + refTimeCombo.select(2); + } + + updateTimeline(); + } + + private void updateTimeline() { + + if (timeMatcher.getFrameTimes().isEmpty()) { + if (timeMatcher.getDominantResource() == null) { + setTimelineState("No Dominant Resource Selected", true); + } else if (!timeMatcher.isDataAvailable()) { + // don't disable since the user may still change to use a time + // interval + setTimelineState("No Data Available For " + + timeMatcher.getDominantResourceName().toString(), + false);// true ); + } else { + setTimelineState( + "No Data Available Within Selected Time Range", false); + } + + timeData = new TimelineData(new ArrayList()); + } else { + + List availTimes = toCalendar(timeMatcher + .getSelectableDataTimes()); + + // this shouldn't happen. If there are no times then the caller + // should set the state based on the reason there are no times. + if (availTimes == null || availTimes.isEmpty()) { + setTimelineState("Timeline Disabled", true); + availTimes = new ArrayList(); + } else if (availTimes.isEmpty()) { + setTimelineState("Timeline Disabled", true); + } else { + timelineStateMessage = null; + setControlsEnabled(true); + } + + // append data at the end to fill the snap peried + snapAvailtimes(availTimes); + + timeData = new TimelineData(availTimes); + + removeSpinnerListeners(); + + // these can trigger the modify listeners too... + hasDifferentMinutes = checkTimeMinutes(availTimes); + + List seldTimes = toCalendar(timeMatcher.getFrameTimes()); + + // only one frame + if (!seldTimes.isEmpty()) { + Calendar seldTime = seldTimes.get(seldTimes.size() - 1); + + seldTime = GraphTimelineUtil.snapTimeToNext(seldTime, + timeMatcher.getHourSnap()); + timeData.select(seldTime); + + int graphSize = timeMatcher.getGraphRange() * 60 + 1; + for (int i = 0; i < graphSize; i++) { + seldTime.add(Calendar.MINUTE, -1); + timeData.select(seldTime); + } + + } + + // if this is a forecast dominant resource, the reference time + // is not needed since the cycle time is the reference time. + refTimeCombo.setVisible(!timeMatcher.isForecast()); + refTimeLbl.setVisible(!timeMatcher.isForecast()); + + setGraphRangeCombo(timeMatcher.getGraphRange()); + + setHourSnapCombo(timeMatcher.getHourSnap()); + + setFrameInterval(timeMatcher.getFrameInterval()); + + setTimeRangeHrs(timeMatcher.getTimeRange()); + + addSpinnerListeners(); + + resetSlider(); + canvas.redraw(); + } + } + + private void snapAvailtimes(List availTimes) { + int snap = timeMatcher.getHourSnap(); + if (snap != 0) { + // && timeMatcher.getDominantResourceName().getRscCategory() + // .getCategoryName().equals("TIMESERIES")) { + GraphTimelineUtil.sortAvailableCalendar(availTimes); + Calendar lastAvail = availTimes.get(availTimes.size() - 1); + + int hour = lastAvail.get(Calendar.HOUR_OF_DAY); + int min = lastAvail.get(Calendar.MINUTE); + if (!(hour % snap == 0 && min == 0)) { + int fillSize = snap * 60 - (hour % snap * 60 + min); + for (int i = 0; i < fillSize; i++) { + lastAvail.add(Calendar.MINUTE, 1); + availTimes.add(lastAvail); + } + } + } + } + + private void setControlsEnabled(boolean enable) { + + graphRangeCombo.setEnabled(enable); + hourSnapCombo.setEnabled(enable); + timeRangeDaysSpnr.setEnabled(enable); + timeRangeHrsSpnr.setEnabled(enable); + frameIntervalCombo.setEnabled(enable); + refTimeCombo.setEnabled(enable); + canvas.setEnabled(enable); + } + + private List toCalendar(List times) { + if (times == null) + return null; + + List timelist = new ArrayList(); + for (DataTime dt : times) { + timelist.add(dt.getValidTime()); + } + return timelist; + } + + /** + * Returns a list of the selected data times. + * + * @return + */ + public List getSelectedTimes() { + ArrayList list = new ArrayList(); + int selectedRange = timeMatcher.getGraphRange() * 60; + + // Calendar lastSelected = timeData.getFirstSelected(); + // if (lastSelected == null) + // return list; + // + // GraphTimelineUtil.snapTimeToNext(lastSelected, + // timeMatcher.getHourSnap()); + // + // lastSelected.add(Calendar.HOUR_OF_DAY, -selectedRange / 60); + // timeData.deselectAll(); + // list.add(lastSelected); + // for (int i = 0; i < selectedRange; i++) { + // + // lastSelected.add(Calendar.MINUTE, +1); + // Calendar cal = (Calendar) lastSelected.clone(); + // list.add(cal); + // } + // System.out.println("**times " + list.size() + " " + // + list.get(0).get(Calendar.HOUR_OF_DAY)); + Calendar firstSelected = timeData.getFirstSelected(); + if (firstSelected == null) + return list; + + firstSelected = GraphTimelineUtil.snapTimeToClosest(firstSelected, + timeMatcher.getHourSnap()); + + // firstSelected.add(Calendar.HOUR_OF_DAY, selectedRange / 60); + timeData.deselectAll(); + list.add(firstSelected); + for (int i = 0; i < selectedRange; i++) { + + firstSelected.add(Calendar.MINUTE, +1); + Calendar cal = (Calendar) firstSelected.clone(); + list.add(cal); + timeData.select(cal); + } + + return list; + // return timeData.getSelectedTimes(); + } + + private void removeSpinnerListeners() { + + for (Listener each : graphRangeCombo.getListeners(SWT.Modify)) { + graphRangeCombo.removeListener(SWT.Modify, each); + } + for (Listener each : hourSnapCombo.getListeners(SWT.Modify)) { + hourSnapCombo.removeListener(SWT.Modify, each); + } + for (Listener each : timeRangeDaysSpnr.getListeners(SWT.Modify)) { + timeRangeDaysSpnr.removeListener(SWT.Modify, each); + } + for (Listener each : timeRangeHrsSpnr.getListeners(SWT.Modify)) { + timeRangeHrsSpnr.removeListener(SWT.Modify, each); + } + } + + private void addSpinnerListeners() { + + timeRangeDaysSpnr.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (timeRangeHrs == timeRangeDaysSpnr.getSelection() * 24 + + timeRangeHrsSpnr.getSelection()) { + return; + } + timeRangeHrs = timeRangeDaysSpnr.getSelection() * 24 + + timeRangeHrsSpnr.getSelection(); + + if (timeRangeHrs == 0) { + timeRangeHrsSpnr.setSelection(1); + } else { + timeMatcher.setTimeRange(timeRangeHrs); + + timeMatcher.generateTimeline(); + + updateTimeline(); + } + } + }); + + timeRangeHrsSpnr.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (timeRangeHrs == timeRangeDaysSpnr.getSelection() * 24 + + timeRangeHrsSpnr.getSelection()) { + return; + } + timeRangeHrs = timeRangeDaysSpnr.getSelection() * 24 + + timeRangeHrsSpnr.getSelection(); + + if (timeRangeHrs == 0) { + timeRangeHrsSpnr.setSelection(1); + } else { + timeMatcher.setTimeRange(timeRangeHrs); + + timeMatcher.generateTimeline(); + + updateTimeline(); + } + } + }); + } + + /* + * Determines whether every data time is specified at the same minute of the + * hour. + */ + private boolean checkTimeMinutes(List times) { + + if (times.isEmpty()) + return false; + + int min = times.get(0).get(Calendar.MINUTE); + for (Calendar cal : times) { + if (min != cal.get(Calendar.MINUTE)) + return true; + } + return false; + } + + /* + * Create all the widgets used for the timeline + */ + private void createWidgets(Composite top_form) { + + createControlWidgets(top_form); + + /* + * set up canvas on which time line display is drawn + */ + canvas = new Canvas(top_form, SWT.BORDER); + FormData fd = new FormData(); + fd.top = new FormAttachment(graphRangeCombo, 10, SWT.BOTTOM); + fd.left = new FormAttachment(0, 10); + fd.bottom = new FormAttachment(100, 0); + fd.right = new FormAttachment(100, 0); + + canvas.setLayoutData(fd); + + canvas.setFont(canvasFont); + canvas.setBackground(canvasColor); + + canvas.addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + // displays the timeline in the canvas + drawTimeline((Canvas) e.getSource(), e.gc); + } + }); + + canvas.addControlListener(new ControlListener() { + @Override + public void controlMoved(ControlEvent e) { + } + + @Override + public void controlResized(ControlEvent e) { + resetSlider(); + } + }); + + canvas.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + canvasFont.dispose(); + pointerCursor.dispose(); + resizeCursor.dispose(); + grabCursor.dispose(); + } + }); + + Listener mouse = new Listener() { + /* + * Contains the mouse handler events for selecting/deselecting + * individual data times. AND for moving and resize the slider bar + */ + MODE mode; + + int saveX = 0; + + Rectangle sliderStart; + + boolean dragging = false; + + @Override + public void handleEvent(Event e) { + + if (timelineStateMessage != null) { + return; + } + + switch (e.type) { + + case SWT.MouseDown: + + if (e.button == 1) { + + /* + * If click on an available time, toggle it's status + * between selected and not selected + */ + // Disable now. May need in some case + // for (Rectangle rect : availableTimes.keySet()) { + // if (rect.contains(e.x, e.y)) { + // timeData.toggle(availableTimes.get(rect)); + // if (timeData.numSelected() == 0) { + // // can't turn off only selected time...turn + // // back on + // timeData.toggle(availableTimes.get(rect)); + // } + // resetSlider(); + // canvas.redraw(); + // timeMatcher + // .setFrameTimes(toDataTimes(getSelectedTimes())); + // return; + // } + // } + + /* + * If user grabs center, top or bottom of slider bar, + * move it to new location on mouse up + */ + Rectangle moveSlider = new Rectangle(slider.x + 2, + slider.y - 2, slider.width - 4, + slider.height + 4); + if (moveSlider.contains(e.x, e.y)) { + saveX = e.x; + sliderStart = new Rectangle(slider.x, slider.y, + slider.width, slider.height); + dragging = true; + mode = MODE.MOVE_ALL; + return; + } + + /* + * If user grabs left side of slider bar, adjust its + * location on mouse up + */ + Rectangle leftSide = new Rectangle(slider.x - 2, + slider.y - 2, 4, slider.height + 4); + if (leftSide.contains(e.x, e.y)) { + saveX = e.x; + sliderStart = new Rectangle(slider.x, slider.y, + slider.width, slider.height); + dragging = true; + mode = MODE.MOVE_LEFT; + return; + } + + /* + * If user grabs right side of slider bar, adjust its + * location on mouse up + */ + Rectangle rightSide = new Rectangle(slider.x + + slider.width - 2, slider.y - 2, 4, + slider.height + 4); + if (rightSide.contains(e.x, e.y)) { + saveX = e.x; + sliderStart = new Rectangle(slider.x, slider.y, + slider.width, slider.height); + dragging = true; + mode = MODE.MOVE_RIGHT; + return; + } + } + + break; + + case SWT.MouseMove: + + if (saveX != 0) { // mouse drag is detected + int xdiff = e.x - saveX; + + switch (mode) { + + case MOVE_ALL: + moveSlider(sliderStart, xdiff); + break; + case MOVE_LEFT: + moveLeftSide(sliderStart, xdiff); + break; + case MOVE_RIGHT: + moveRightSide(sliderStart, xdiff); + break; + } + + canvas.redraw(); + } else if (slider != null) { // No drag detected...set + // appropriate cursor + + Rectangle moveSlider = new Rectangle(slider.x + 2, + slider.y - 2, slider.width - 4, + slider.height + 4); + Rectangle leftSide = new Rectangle(slider.x - 2, + slider.y - 2, 4, slider.height + 4); + Rectangle rightSide = new Rectangle(slider.x + + slider.width - 2, slider.y - 2, 4, + slider.height + 4); + + if (moveSlider.contains(e.x, e.y)) { + canvas.setCursor(grabCursor); + } else if (leftSide.contains(e.x, e.y) + || rightSide.contains(e.x, e.y)) { + canvas.setCursor(resizeCursor); + } else { + canvas.setCursor(pointerCursor); + } + } + + break; + + case SWT.MouseUp: + if (!dragging) { + return; + } + + dragging = false; + + if (e.button == 1) { + + if (saveX == e.x) { // mouse did not move. reset + saveX = 0; + return; + } + + if (saveX != 0) { // mouse drag is detected + int xdiff = e.x - saveX;// before mouse up + + // get snap distance ratio + int snap = timeMatcher.getHourSnap(); + + Calendar first = timeData.getFirstTime(); + Calendar last = timeData.getLastTime(); + int total = (int) (last.getTimeInMillis() - first + .getTimeInMillis()); + + double snapRatio = (double) (snap * 3600 * 1000) + / (double) total; + + Point size = canvas.getSize(); + int lineY = Math.round((float) size.y * TIME_LINE); + Point beg = new Point(MARGIN, lineY); + Point end = new Point(size.x - MARGIN - 1, lineY); + + double snapDist = (double) (end.x - beg.x) + * snapRatio; + + double snapNum = (double) Math.abs(xdiff) + / (double) snapDist; + int snapNumRound = (int) Math.round(snapNum); + + switch (mode) { + + case MOVE_ALL: { + + int snapX = 0; + Calendar firstSelected = timeData + .getFirstSelected(); + Calendar lastSelected = timeData + .getLastSelected(); + lastSelected = GraphTimelineUtil + .snapTimeToNext(lastSelected, snap); + + int firstSelectedX = currPositionFromTime(firstSelected);// + int lastSelectedX = currPositionFromTime(lastSelected); + + Calendar snapped = null; + + if (e.x <= saveX) { + snapped = (Calendar) firstSelected.clone(); + snapped.add(Calendar.HOUR_OF_DAY, -snap + * snapNumRound); + snapX = currPositionFromTime(snapped); + xdiff = snapX - firstSelectedX; + } else if (e.x > saveX) { + snapped = (Calendar) lastSelected.clone(); + snapped.add(Calendar.HOUR_OF_DAY, snap + * snapNumRound); + snapX = currPositionFromTime(snapped); + xdiff = snapX - lastSelectedX; + } + + moveSlider(sliderStart, xdiff); + break; + } + case MOVE_LEFT: { + + int snapX = 0; + Calendar curr = currTimeFromPosition(e.x); + + Calendar snapped = (Calendar) curr.clone(); + if (snapNumRound == 0) { + snapped = GraphTimelineUtil.snapTimeToNext( + snapped, snap); + xdiff = 0; + } else { + if (e.x <= saveX) { + + snapped = GraphTimelineUtil + .snapTimeToClosest(snapped, + snap); + newGraphRange = timeMatcher + .getGraphRange() + + (snap * snapNumRound); + setGraphRangeCombo(newGraphRange); + } else { + + snapped = GraphTimelineUtil + .snapTimeToClosest(snapped, + snap); + newGraphRange = timeMatcher + .getGraphRange() + - (snap * snapNumRound); + setGraphRangeCombo(newGraphRange); + } + + snapX = currPositionFromTime(snapped); + xdiff = snapX - saveX; + } + + moveLeftSide(sliderStart, xdiff); + + break; + } + case MOVE_RIGHT: { + + int snapX = 0; + Calendar curr = currTimeFromPosition(e.x); + + Calendar snapped = (Calendar) curr.clone(); + + if (snapNumRound == 0) { + snapped = GraphTimelineUtil + .snapTimeToPrevious(snapped, snap); + xdiff = 0; + } else { + if (e.x <= saveX) { + + snapped = GraphTimelineUtil + .snapTimeToClosest(snapped, + snap); + newGraphRange = timeMatcher + .getGraphRange() + - (snap * snapNumRound); + setGraphRangeCombo(newGraphRange); + } else { + + snapped = GraphTimelineUtil + .snapTimeToClosest(snapped, + snap); + newGraphRange = timeMatcher + .getGraphRange() + + (snap * snapNumRound); + setGraphRangeCombo(newGraphRange); + } + + snapX = currPositionFromTime(snapped); + xdiff = snapX - saveX; + } + + moveRightSide(sliderStart, xdiff); + + break; + } + } + + saveX = 0; // reset + updateSelectedTimes(xdiff); + + canvas.redraw(); + } + + } + + break; + } + } + }; + + canvas.addListener(SWT.MouseDown, mouse); + canvas.addListener(SWT.MouseMove, mouse); + canvas.addListener(SWT.MouseUp, mouse); + + graphRangeCombo.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + for (int i = 0; i < availGraphRangeStrings.length; i++) { + if (availGraphRangeStrings[i].equals(graphRangeCombo + .getText())) { + timeMatcher.setGraphRange(availGraphRangeHrs[i]); + break; + } + } + + timeMatcher.generateTimeline(); + + updateTimeline(); + } + }); + + hourSnapCombo.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + for (int i = 0; i < availHourSnapStrings.length; i++) { + if (availHourSnapStrings[i].equals(hourSnapCombo.getText())) { + timeMatcher.setHourSnap(availHourSnapHrs[i]); + break; + } + } + + timeMatcher.generateTimeline(); + + updateTimeline(); + } + }); + + frameIntervalCombo.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + for (int i = 0; i < availFrameIntervalStrings.length; i++) { + if (availFrameIntervalStrings[i].equals(frameIntervalCombo + .getText())) { + timeMatcher.setFrameInterval(availFrameIntervalMins[i]); + break; + } + } + + timeMatcher.generateTimeline(); + + updateTimeline(); + } + }); + + refTimeCombo.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (refTimeCombo.getSelectionIndex() == 0) { + timeMatcher.setCurrentRefTime(); + } else if (refTimeCombo.getSelectionIndex() == 1) { + timeMatcher.setLatestRefTime(); + } else if (refTimeCombo.getSelectionIndex() == 2) { + + CalendarSelectDialog calSelDlg = new CalendarSelectDialog( + shell); + + DataTime newRefTime = calSelDlg.open(timeMatcher + .getRefTime()); + if (newRefTime != null) { + timeMatcher.setRefTime(newRefTime); + } else { + return; + } + + } + + timeMatcher.generateTimeline(); + updateTimeline(); + } + }); + } + + /* + * Creates control widgets above the timeline canvas + */ + private void createControlWidgets(Composite top_form) { + FormData fd = new FormData(); + + graphRangeCombo = new Combo(top_form, SWT.DROP_DOWN); + fd = new FormData(); + fd.width = 20; + fd.top = new FormAttachment(dom_rsc_combo, 50, SWT.BOTTOM); + fd.left = new FormAttachment(5, 0); + fd.right = new FormAttachment(5, 80); + graphRangeCombo.setLayoutData(fd); + + graphRangeCombo.setItems(availGraphRangeStrings); + + Label graphRangeLbl = new Label(top_form, SWT.NONE); + graphRangeLbl.setText("Selected\nRange"); + fd = new FormData(); + fd.bottom = new FormAttachment(graphRangeCombo, -3, SWT.TOP); + fd.left = new FormAttachment(graphRangeCombo, 0, SWT.LEFT); + graphRangeLbl.setLayoutData(fd); + + hourSnapCombo = new Combo(top_form, SWT.DROP_DOWN | SWT.READ_ONLY); + fd = new FormData(); + fd.top = new FormAttachment(graphRangeCombo, 0, SWT.TOP); + fd.left = new FormAttachment(20, 20); + fd.right = new FormAttachment(20, 70); + hourSnapCombo.setLayoutData(fd); + hourSnapCombo.setItems(availHourSnapStrings); + + Label hourSnapLbl = new Label(top_form, SWT.NONE); + hourSnapLbl.setText("Snap\nHours"); + fd = new FormData(); + fd.bottom = new FormAttachment(hourSnapCombo, -3, SWT.TOP); + fd.left = new FormAttachment(hourSnapCombo, 0, SWT.LEFT); + hourSnapLbl.setLayoutData(fd); + + timeRangeDaysSpnr = new Spinner(top_form, SWT.BORDER); + fd = new FormData(); + fd.top = new FormAttachment(graphRangeCombo, 0, SWT.TOP); + fd.left = new FormAttachment(36, 0); + timeRangeDaysSpnr.setLayoutData(fd); + + Label dfltTimeRangeLbl = new Label(top_form, SWT.NONE); + dfltTimeRangeLbl.setText("Timeline Range\n(Days / Hours)"); + fd = new FormData(); + fd.bottom = new FormAttachment(timeRangeDaysSpnr, -3, SWT.TOP); + fd.left = new FormAttachment(timeRangeDaysSpnr, 0, SWT.LEFT); + dfltTimeRangeLbl.setLayoutData(fd); + + timeRangeDaysSpnr.setMinimum(0); + timeRangeDaysSpnr.setMaximum(999); + timeRangeDaysSpnr.setDigits(0); + timeRangeDaysSpnr.setIncrement(1); + timeRangeDaysSpnr.setTextLimit(4); + timeRangeDaysSpnr.setPageIncrement(30); + + timeRangeHrsSpnr = new Spinner(top_form, SWT.BORDER); + fd = new FormData(); + fd.top = new FormAttachment(timeRangeDaysSpnr, 0, SWT.TOP); + fd.left = new FormAttachment(timeRangeDaysSpnr, 8, SWT.RIGHT); + timeRangeHrsSpnr.setLayoutData(fd); + + timeRangeHrsSpnr.setMinimum(0); + timeRangeHrsSpnr.setMaximum(23); + timeRangeHrsSpnr.setDigits(0); + timeRangeHrsSpnr.setIncrement(1); + timeRangeHrsSpnr.setTextLimit(2); + + frameIntervalCombo = new Combo(top_form, SWT.DROP_DOWN | SWT.READ_ONLY); + fd = new FormData(); + fd.top = new FormAttachment(graphRangeCombo, 0, SWT.TOP); + fd.left = new FormAttachment(59, 0); + frameIntervalCombo.setLayoutData(fd); + + frameIntervalCombo.setItems(availFrameIntervalStrings); + + Label frameIntLbl = new Label(top_form, SWT.NONE); + frameIntLbl.setText("Data\nInterval"); + fd = new FormData(); + fd.bottom = new FormAttachment(frameIntervalCombo, -3, SWT.TOP); + fd.left = new FormAttachment(frameIntervalCombo, 0, SWT.LEFT); + frameIntLbl.setLayoutData(fd); + + refTimeCombo = new Combo(top_form, SWT.DROP_DOWN | SWT.READ_ONLY); + fd = new FormData(); + fd.top = new FormAttachment(graphRangeCombo, 0, SWT.TOP); + fd.left = new FormAttachment(80, 0); + refTimeCombo.setLayoutData(fd); + + refTimeCombo.setItems(refTimeSelectionOptions); + + refTimeLbl = new Label(top_form, SWT.NONE); + refTimeLbl.setText("Ref. Time"); + fd = new FormData(); + fd.bottom = new FormAttachment(refTimeCombo, -3, SWT.TOP); + fd.left = new FormAttachment(refTimeCombo, 0, SWT.LEFT); + refTimeLbl.setLayoutData(fd); + } + + /* + * calculates and draws all the time line info + */ + protected void drawTimeline(Canvas canvas, GC gc) { + + Point size = canvas.getSize(); + + int textHeight = gc.getFontMetrics().getHeight(); + + if (timelineStateMessage != null) { + int width = gc.getCharWidth('e') * timelineStateMessage.length(); + gc.drawText(timelineStateMessage, (size.x - width) / 2, + (size.y - textHeight) / 2); + return; + } else if (timeData.isEmpty()) { // shouldn't happen. if empty the state + // should be set + timelineStateMessage = new String("Timeline Empty"); + return; + } + + /* + * draw date line that separates month/days and the hours of day + */ + + int dateY = Math.round((float) size.y * DATE_LINE); + Point begDateLine = new Point(MARGIN, dateY); + Point endDateLine = new Point(size.x - MARGIN - 1, dateY); + + gc.drawLine(begDateLine.x, begDateLine.y, endDateLine.x, endDateLine.y); + + /* + * display months and days of month + */ + calculateDates(begDateLine, endDateLine); + plotDates(gc, begDateLine, endDateLine); + + /* + * draw time line + */ + + int lineY = Math.round((float) size.y * TIME_LINE); + Point begTimeLine = new Point(MARGIN, lineY); + Point endTimeLine = new Point(size.x - MARGIN - 1, lineY); + gc.drawLine(begTimeLine.x, begTimeLine.y, endTimeLine.x, endTimeLine.y); + + plotTickMarks(gc, begTimeLine, endTimeLine, dateY); + + calculateAvailableBoxes(begTimeLine, endTimeLine); + plotAvailableBoxes(gc); + int hourY = (size.y + lineY) / 2; + plotAvailableTimes(gc, hourY); + + /* + * draw slider bar + */ + if (slider == null) + slider = calculateSlider(begTimeLine, endTimeLine); + + gc.setLineWidth(2); + gc.drawRectangle(slider); + gc.setLineWidth(1); + + // display legend + gc.setBackground(availableColor); + gc.fillRectangle(5, size.y - MARKER_HEIGHT - 5, MARKER_WIDTH, + MARKER_HEIGHT); + gc.setBackground(canvasColor); + gc.drawText("available data", 15, size.y - textHeight, true); + gc.setBackground(selectedColor); + gc.fillRectangle(150, size.y - MARKER_HEIGHT - 5, MARKER_WIDTH, + MARKER_HEIGHT); + gc.setBackground(canvasColor); + gc.drawText("selected data", 160, size.y - textHeight, true); + + } + + /* + * Calculate the rectangle defining the slider bar, based on the currently + * selected dates. + */ + private Rectangle calculateSlider(Point beg, Point end) { + + int ulX, lastX; + sliderMin = beg.x - 5; + sliderMax = end.x + 5; + + Calendar time1 = timeData.getFirstSelected(); + Calendar time2 = timeData.getLastSelected(); + + if (time1 == null) + return new Rectangle(0, 0, 0, 0); + + Calendar prev = timeData.getPreviousTime(time1); + if (prev != null) + ulX = (timeLocations.get(prev) + timeLocations.get(time1)) / 2; + else + ulX = sliderMin + 5; + + Calendar next = timeData.getNextTime(time2); + if (next != null && timeLocations.get(next) != null) { + lastX = (timeLocations.get(time2) + timeLocations.get(next)) / 2; + } else + lastX = sliderMax - 5; // ? + + int ulY = beg.y - SLIDER; + int width = lastX - ulX; + int height = 2 * SLIDER; + + return new Rectangle(ulX, ulY, width, height); + } + + private Calendar currTimeFromPosition(int posX) { + Point size = canvas.getSize(); + int lineY = Math.round((float) size.y * TIME_LINE); + Point beg = new Point(MARGIN, lineY); + Point end = new Point(size.x - MARGIN - 1, lineY); + int lineLength = end.x - beg.x; + + double dist = (double) (posX - beg.x) / (double) lineLength; + + Calendar first = timeData.getFirstTime(); + first.setTimeZone(TimeZone.getTimeZone("UTC")); + Calendar last = timeData.getLastTime(); + last.setTimeZone(TimeZone.getTimeZone("UTC")); + + long timeLength = last.getTimeInMillis() - first.getTimeInMillis(); + + long currMills = Math.round(dist * (double) timeLength) + + first.getTimeInMillis(); + + Calendar curr = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + + curr.setTimeInMillis(currMills); + + curr.set(Calendar.SECOND, 0); + curr.set(Calendar.MILLISECOND, 0); + + return curr; + } + + private int currPositionFromTime(Calendar curr) { + Calendar first = timeData.getFirstTime(); + first.setTimeZone(TimeZone.getTimeZone("UTC")); + Calendar last = timeData.getLastTime(); + last.setTimeZone(TimeZone.getTimeZone("UTC")); + long timeLength = last.getTimeInMillis() - first.getTimeInMillis(); + + Point size = canvas.getSize(); + int lineY = Math.round((float) size.y * TIME_LINE); + Point beg = new Point(MARGIN, lineY); + Point end = new Point(size.x - MARGIN - 1, lineY); + int lineLength = end.x - beg.x; + + curr.setTimeZone(TimeZone.getTimeZone("UTC")); + + double dist = (double) (curr.getTimeInMillis() - first + .getTimeInMillis()) / (double) timeLength; + + int currX = (int) Math.round(dist * (double) lineLength) + beg.x; + + return currX; + } + + /* + * calculates a list of days between the first and last available times, and + * calculate each day's relative position along the line defined by the two + * points specified beg and end + */ + private void calculateDates(Point beg, Point end) { + + days = new ArrayList(); + dayLocation = new ArrayList(); + int lineLength = end.x - beg.x; + + Calendar first = timeData.getFirstTime(); + Calendar last = timeData.getLastTime(); + long timeLength = timeData.getTotalMillis(); + + Calendar cal = (Calendar) first.clone(); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + + while (cal.before(last)) { + + if (cal.before(first)) { + days.add(cal); + dayLocation.add(beg.x); + } else { + double dist = (double) (cal.getTimeInMillis() - first + .getTimeInMillis()) / (double) timeLength; + long lineDist = Math.round(dist * (double) lineLength); + days.add(cal); + dayLocation.add(beg.x + (int) lineDist); + } + + cal = (Calendar) cal.clone(); + cal.add(Calendar.DAY_OF_YEAR, 1); + } + + } + + /* + * plot days and month names + */ + private void plotDates(GC gc, Point beg, Point end) { + + if (days.size() <= MAX_DATES) { + plotDays(gc, beg, end, "MMMdd", true); + } else { + plotDays(gc, beg, end, "dd", false); + plotMonths(gc, beg, end); + } + } + + /* + * plots the label of each day in the available times range + */ + private void plotDays(GC gc, Point beg, Point end, String fmt, + boolean center) { + + SimpleDateFormat sdf = new SimpleDateFormat(fmt); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + int textHeight = gc.getFontMetrics().getHeight(); + int width = gc.getCharWidth('0'); + int halfWidth = (width * fmt.length()) / 2; + int locY = beg.y - textHeight; + if (center) + locY = (beg.y - textHeight) / 2; + + int numdays = days.size(); + + for (int j = 0; j < numdays; j++) { + + Calendar cal = days.get(j); + int startX = dayLocation.get(j); + int endX = end.x; + if (j < (numdays - 1)) { + endX = dayLocation.get(j + 1); + } + + String hour = sdf.format(cal.getTime()); + int locX = (endX + startX) / 2 - halfWidth; + if (locX > startX) + gc.drawText(hour, locX, locY); + + if (j != 0) + gc.drawLine(startX, locY, startX, beg.y); // separator + + } + + } + + /* + * plots the label of each month in the available times range + */ + private void plotMonths(GC gc, Point beg, Point end) { + + String fmt = new String("MMM"); + SimpleDateFormat sdf = new SimpleDateFormat(fmt); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + int width = gc.getCharWidth('0'); + int halfWidth = (width * fmt.length()) / 2; + int locY = 0; + + Calendar first = days.get(0); + Calendar last = days.get(days.size() - 1); + + if (first.get(Calendar.MONTH) == last.get(Calendar.MONTH)) { + String month = sdf.format(first.getTime()); + int locX = (end.x + beg.x) / 2 - halfWidth; + gc.drawText(month, locX, locY, true); + } else { + int locX = 0; + for (Calendar cal : days) { + if (cal.get(Calendar.DAY_OF_MONTH) == 1) { + int index = days.indexOf(cal); + locX = dayLocation.get(index); + break; + } + } + + gc.drawLine(locX, locY, locX, beg.y); // separator + + String month = sdf.format(first.getTime()); + int startX = (locX + beg.x) / 2 - halfWidth; + gc.drawText(month, startX, locY, true); + + month = sdf.format(last.getTime()); + startX = (end.x + locX) / 2 - halfWidth; + gc.drawText(month, startX, locY, true); + } + } + + /* + * draws tick marks along the timeline defined by the two given endpoints + * beg and end + */ + private void plotTickMarks(GC gc, Point beg, Point end, int dateY) { + int prevX = -9999; + int lineLength = end.x - beg.x; + + SimpleDateFormat sdf = new SimpleDateFormat("HH"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + Calendar first = timeData.getFirstTime(); + Calendar last = timeData.getLastTime(); + + int textHeight = gc.getFontMetrics().getHeight(); + int width = gc.getCharWidth('0'); + int locY = (dateY + beg.y) / 2; + int overlap = width * 3; // 3 characters + + long timeLength = timeData.getTotalMillis(); + int totalMinutes = timeData.getTotalMinutes(); + int timeInterval = calcTimeInterval(lineLength, totalMinutes); // in + // minutes + + Calendar cal = (Calendar) first.clone(); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + + while (cal.before(last)) { + if (cal.before(first)) { + cal.add(Calendar.MINUTE, timeInterval); + continue; + } + double dist = (double) (cal.getTimeInMillis() - first + .getTimeInMillis()) / (double) timeLength; + long lineDist = Math.round(dist * (double) lineLength); + int locX = beg.x + (int) lineDist; + int tickSize; + if (hasDifferentMinutes) { + tickSize = (cal.get(Calendar.MINUTE) == 0) ? TICK_LARGE + : TICK_SMALL; + } else { + tickSize = (cal.get(Calendar.HOUR_OF_DAY) % 3 == 0) ? TICK_LARGE + : TICK_SMALL; + } + gc.drawLine(locX, beg.y - tickSize, locX, beg.y + tickSize); + + /* + * label the tick mark with the hour of the day, if room. + */ + String hour = sdf.format(cal.getTime()); + int x = locX - width; + int y = locY - (textHeight / 2); + if (x > (prevX + overlap)) { + gc.drawText(hour, x, y); + prevX = x; + } + + cal.add(Calendar.MINUTE, timeInterval); // time of next tick mark + } + } + + /* + * calculates an appropriate time interval (in minutes) to use for tick + * marks along the timeline + */ + private int calcTimeInterval(int lineLength, int minutes) { + int interval = 15; + int maxnum = lineLength / 4; + + if (hasDifferentMinutes) { + if ((minutes / interval) > maxnum) + interval = 30; + if ((minutes / interval) > maxnum) + interval = 60; + } else { + interval = 60; + } + + if ((minutes / interval) > maxnum) + interval = 180; + if ((minutes / interval) > maxnum) + interval = 360; + if ((minutes / interval) > maxnum) + interval = 720; + if ((minutes / interval) > maxnum) + interval = 1440; + + return interval; + } + + /* + * Calculate the boxes and their locations that will be used to represent + * the available times on the timeline + */ + private void calculateAvailableBoxes(Point beg, Point end) { + + availableTimes = new LinkedHashMap(); + timeLocations = new HashMap(); + + int lineLength = end.x - beg.x; + + Calendar first = timeData.getFirstTime(); + + long timeLength = timeData.getTotalMillis(); + + for (Calendar curr : timeData.getTimes()) { + // the last data is next snap 00:00, so don't put it to + // availableTimes. + if (timeData.getNextTime(curr) != null) { + double dist = (double) (curr.getTimeInMillis() - first + .getTimeInMillis()) / (double) timeLength; + long lineDist = Math.round(dist * (double) lineLength); + int locX = beg.x + (int) lineDist - (MARKER_WIDTH / 2); + int locY = beg.y - (MARKER_HEIGHT / 2); + + Rectangle box = new Rectangle(locX, locY, MARKER_WIDTH, + MARKER_HEIGHT); + availableTimes.put(box, curr); + timeLocations.put(curr, beg.x + (int) lineDist); + } + } + } + + /* + * draw boxes representing availbale times on timeline. Selected times are + * displayed in a different color + */ + private void plotAvailableBoxes(GC gc) { + + gc.setBackground(availableColor); + for (Rectangle rect : availableTimes.keySet()) { + gc.setBackground(availableColor); + if (timeData.isSelected(availableTimes.get(rect))) { + gc.setBackground(selectedColor); + + } + gc.fillRectangle(rect); + } + + gc.setBackground(canvasColor); + } + + /* + * Label each available box with the hour or minute of the time represented + * by the box + */ + private void plotAvailableTimes(GC gc, int hourY) { + int prevX = -9999; + + SimpleDateFormat sdf = new SimpleDateFormat("HH"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + if (hasDifferentMinutes) + sdf.applyPattern("mm"); + + int textHeight = gc.getFontMetrics().getHeight(); + int width = gc.getCharWidth('0'); + int overlap = width * 3; // 3 characters + + for (Rectangle rect : availableTimes.keySet()) { + Calendar cal = availableTimes.get(rect); + String hour = sdf.format(cal.getTime()); + int x = rect.x + (rect.width / 2) - width; + int y = hourY - (textHeight / 2); + if (x > (prevX + overlap)) { + gc.drawText(hour, x, y); + prevX = x; + } + } + } + + /** + * Sets the number of times that should be selected + * + * @param num + */ + // public void setNumberofFrames(int num) { + // numFramesSpnr.setSelection(Math.min(num, + // (timeData != null ? timeData.getSize() : 0))); + // } + + /** + * Retuns the current skip factor used + * + * @return + */ + public int getHourSnapCombo() { + return timeMatcher.getHourSnap(); // hourSnapCombo.getSelectionIndex(); + } + + /** + * Sets the snap factor + * + * @param num + */ + public void setHourSnapCombo(int num) { + timeMatcher.setHourSnap(num); + + hourSnapCombo.deselectAll(); + + for (int i = 0; i < availHourSnapHrs.length; i++) { + if (availHourSnapHrs[i] == num) { + hourSnapCombo.select(i); + break; + } + } + } + + public int getGraphRangeCombo() { + return timeMatcher.getGraphRange(); + } + + public void setGraphRangeCombo(int num) { + timeMatcher.setGraphRange(num); + + graphRangeCombo.deselectAll(); + boolean isInCombo = false; + for (int i = 0; i < availGraphRangeHrs.length; i++) { + if (availGraphRangeHrs[i] == num) { + graphRangeCombo.select(i); + isInCombo = true; + break; + } + } + + if (!isInCombo) { + graphRangeCombo.setText(String.valueOf(num) + " hrs"); + } + } + + public void setFrameInterval(int fInt) { + timeMatcher.setFrameInterval(fInt); + + frameIntervalCombo.deselectAll(); + + for (int i = 0; i < availFrameIntervalMins.length; i++) { + if (availFrameIntervalMins[i] == fInt) { + frameIntervalCombo.select(i); + break; + } + } + } + + public int getFrameInterval() { + return timeMatcher.getFrameInterval(); + } + + public int getTimeRangeHrs() { + return timeRangeHrs; + } + + public void setTimeRangeHrs(int tRangeHrs) { + if (timeRangeHrs == tRangeHrs) { + return; + } + + timeRangeHrs = tRangeHrs; + + timeRangeDaysSpnr.setSelection(timeRangeHrs / 24); + timeRangeHrsSpnr.setSelection(timeRangeHrs % 24); + } + + /* + * resets the slider bar so that it is recalculated using the selected times + */ + private void resetSlider() { + slider = null; + } + + /* + * Moves the slider bar the specified number of pixels (pos) + */ + private void moveSlider(Rectangle start, int pos) { + + Rectangle whole = new Rectangle(sliderMin, slider.y, sliderMax + - sliderMin, slider.height); + start.x += pos; + slider = whole.intersection(start); + start.x -= pos; + + } + + /* + * Moves the left side of the slider bar the specified number of pixels + * (pos) + */ + private void moveLeftSide(Rectangle start, int pos) { + /* + * deal with snap + */ + int startX = start.x + pos; + int width = start.width - pos; + if (startX < sliderMin) { + startX = sliderMin; + width = start.x + start.width - sliderMin; + } + slider = new Rectangle(startX, start.y, width, start.height); + } + + /* + * Moves the right side of the slider bar the specified number of pixels + * (pos) + */ + private void moveRightSide(Rectangle start, int pos) { + int width = start.width + pos; + if (start.x + width > sliderMax) + width = sliderMax - start.x; + slider = new Rectangle(start.x, start.y, width, start.height); + } + + /* + * update the selected status of each available time that is currently in + * the slider bar based on current behavior and skip factor + */ + private void updateSelectedTimes(int xdiff) { + + if (availableTimes == null || slider == null) + return; // canvas not yet ready + + Calendar first = null; + Calendar last = null; + + /* + * determine first and last available data time in slider bar + */ + for (Rectangle rect : availableTimes.keySet()) { + if (slider.intersects(rect)) { + + Calendar cal = availableTimes.get(rect); + if (first == null) + first = cal; + if (last == null) + last = cal; + if (cal.before(first)) + first = cal; + if (cal.after(last)) + last = cal; + } + } + + /* + * If no available times in slider, must select at least one + */ + if (first == null || last == null) { + if (slider.x == 0) { + timeData.deselectAll(); + if (timeMatcher.isForecast()) { + timeData.select(timeData.getFirstTime()); + } else { + timeData.select(timeData.getLastTime()); + } + + timeMatcher.setFrameTimes(toDataTimes(getSelectedTimes())); + } + + resetSlider(); + return; + } + + /* + * reset status of each data time in slider bar. + */ + // System.out.println("**first " + first.toString() + " " + // + last.toString()); + // int snap = timeMatcher.getHourSnap(); + // first = GraphTimelineUtil.snapTimeToClosest(first, snap); + // last = (Calendar) first.clone(); + // last.add(Calendar.HOUR_OF_DAY, newGraphRange); + // System.out.println("first " + first.get(Calendar.HOUR_OF_DAY) + " " + // + first.get(Calendar.MINUTE) + " " + last.get(Calendar.MINUTE)); + if (timeMatcher.isForecast()) { + timeData.updateRange(first, last, 0); + } else { + timeData.updateRange(last, first, 0); + } + // List cals = new ArrayList(); + // cals.add(timeData.getFirstSelected()); + timeMatcher.setFrameTimes(toDataTimes(timeData.getSelectedTimes())); // getSelectedTimes())); + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineControl.java index df7d298dba..a1d5e54f8e 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineControl.java @@ -85,6 +85,7 @@ import com.raytheon.uf.common.time.DataTime; * 02/11/11 #408 Greg Hull combined with Timeline class (now TimelineControl) * 06/19/12 #657 Greg Hull removeSpinnerListeners() before setting the * spinner maxvalues. + * 04/30/2014 #1131 qzhou Add construct for Graph to create graph widgets. * 06/24/14 TTR1029 J. Wu Distinguish clicks in/outside of the slider box. * 07/11/14 TTR1032 J. Wu reload data times as necessary to keep timeline current. * @@ -121,20 +122,20 @@ public class TimelineControl extends Composite { private final String manualTimelineStr = " Manual Timeline "; - private HashMap> availDomResourcesMap = null; + protected HashMap> availDomResourcesMap = null; - private AbstractNatlCntrsRequestableResourceData domRscData = null; + protected AbstractNatlCntrsRequestableResourceData domRscData = null; - private Combo dom_rsc_combo = null; + protected Combo dom_rsc_combo = null; - private NCTimeMatcher timeMatcher = null; + protected NCTimeMatcher timeMatcher = null; public interface IDominantResourceChangedListener { public void dominantResourceChanged( AbstractNatlCntrsRequestableResourceData newDomRsc); } - private Set dominantResourceChangedListeners = new HashSet(); + protected Set dominantResourceChangedListeners = new HashSet(); // public enum TimeLineBehavior { PREPEND, APPEND }; private enum MODE { @@ -205,7 +206,7 @@ public class TimelineControl extends Composite { private int sliderMin, sliderMax; - private TimelineData timeData; + protected TimelineData timeData; private Map availableTimes; @@ -221,8 +222,14 @@ public class TimelineControl extends Composite { private Shell shell; + public TimelineControl(Composite parent, String rbdName) { + super(parent, SWT.NONE); + // this.rbdName = rbdName; + } + public TimelineControl(Composite parent) { super(parent, SWT.NONE); + shell = parent.getShell(); timeMatcher = new NCTimeMatcher(); @@ -347,6 +354,7 @@ public class TimelineControl extends Composite { } return true; + } public NCTimeMatcher getTimeMatcher() { @@ -616,7 +624,6 @@ public class TimelineControl extends Composite { // private void updateTimeline() { - // if (timeMatcher.getFrameTimes().isEmpty()) { if (timeMatcher.getDominantResource() == null) { setTimelineState("No Dominant Resource Selected", true); diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineData.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineData.java index 5d0ca7dd16..56ee959b4f 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineData.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/timeline/TimelineData.java @@ -16,386 +16,410 @@ import java.util.Set; import java.util.TreeMap; /** - * This class maintains an ordered map of data times, where each time - * is mapped to a Boolean value indicating whether that time is "selected" from - * the overall list. + * This class maintains an ordered map of data times, where each time is mapped + * to a Boolean value indicating whether that time is "selected" from the + * overall list. * * @author sgilbert - * + * */ public class TimelineData { - private TreeMap times; + private TreeMap times; - /** - * Initializes all available time to non-selected status - * @param timeList list of available data times - */ - TimelineData( List timeList ) { + /** + * Initializes all available time to non-selected status + * + * @param timeList + * list of available data times + */ + TimelineData(List timeList) { - times = new TreeMap(); - for ( Calendar cal : timeList ) { - times.put(cal, false); - } + times = new TreeMap(); + for (Calendar cal : timeList) { + times.put(cal, false); + } - } - - /** - * checks if the list of available times is empty - * @return - */ - public boolean isEmpty() { - return times.isEmpty(); - } + } - /** - * Returns the first available data time in the list - * @return - */ - public Calendar getFirstTime() { - return times.firstKey(); - } - - /** - * Returns the last available data time in the list - * @return - */ - public Calendar getLastTime() { - return times.lastKey(); - } + /** + * checks if the list of available times is empty + * + * @return + */ + public boolean isEmpty() { + return times.isEmpty(); + } - /** - * Returns a set of all the available data times - * @return - */ - public Set getTimes() { - return times.keySet(); - } - - /** - * Returns a list of "selected" data times from the list of available times - * @return - */ - public List getSelectedTimes() { - ArrayList list = new ArrayList(); - for ( Calendar cal : times.keySet() ) { - if ( times.get(cal) ) list.add(cal); - } - return list; - } + /** + * Returns the first available data time in the list + * + * @return + */ + public Calendar getFirstTime() { + return times.firstKey(); + } - /** - * Checks if the specified time is selected - */ - public boolean isSelected(Calendar cal) { - return times.get(cal); - } - - /** - * Returns the total number of minutes between the first and last available - * data times - * @return - */ - public int getTotalMinutes() { - Calendar first = getFirstTime(); - Calendar last = getLastTime(); - long timeLength = last.getTimeInMillis() - first.getTimeInMillis(); - return (int)(timeLength/60000); - } + /** + * Returns the last available data time in the list + * + * @return + */ + public Calendar getLastTime() { + return times.lastKey(); + } - /** - * Returns the total number of milliseconds between the first and last available - * data times - * @return - */ - public long getTotalMillis() { - Calendar first = getFirstTime(); - Calendar last = getLastTime(); - return last.getTimeInMillis() - first.getTimeInMillis(); - } + /** + * Returns a set of all the available data times + * + * @return + */ + public Set getTimes() { + return times.keySet(); + } - /* - public void selectFirst(int num) { - - int j=0; - Calendar cal = times.firstKey(); - while ( cal != null ) { - if ( j++ < num ) times.put(cal, true); - else times.put(cal, false); - - cal = times.higherKey( cal ); - } - } - - public void selectLast(int num) { + /** + * Returns a list of "selected" data times from the list of available times + * + * @return + */ + public List getSelectedTimes() { + ArrayList list = new ArrayList(); + for (Calendar cal : times.keySet()) { + if (times.get(cal)) + list.add(cal); + } + return list; + } - int j=0; - Calendar cal = times.lastKey(); - while ( cal != null ) { - if ( j++ < num ) times.put(cal, true); - else times.put(cal, false); - - cal = times.lowerKey( cal ); - } - - } - */ + /** + * Checks if the specified time is selected + */ + public boolean isSelected(Calendar cal) { + return times.get(cal); + } - /** - * Returns the first selected time in the list - */ - public Calendar getFirstSelected() { - - Map.Entry entry = times.firstEntry(); - while ( entry != null ) { - if ( entry.getValue() ) return entry.getKey(); - entry = times.higherEntry( entry.getKey() ); - } - return null; - } + /** + * Returns the total number of minutes between the first and last available + * data times + * + * @return + */ + public int getTotalMinutes() { + Calendar first = getFirstTime(); + Calendar last = getLastTime(); + long timeLength = last.getTimeInMillis() - first.getTimeInMillis(); + return (int) (timeLength / 60000); + } - /** - * Returns the last selected time in the list - * @return - */ - public Calendar getLastSelected() { - - Map.Entry entry = times.lastEntry(); - while ( entry != null ) { - if ( entry.getValue() ) return entry.getKey(); - entry = times.lowerEntry( entry.getKey() ); - } - return null; - } + /** + * Returns the total number of milliseconds between the first and last + * available data times + * + * @return + */ + public long getTotalMillis() { + Calendar first = getFirstTime(); + Calendar last = getLastTime(); + return last.getTimeInMillis() - first.getTimeInMillis(); + } - /** - * Returns the available time just before the specified time - * @param cal - * @return - */ - public Calendar getPreviousTime(Calendar cal) { - return times.lowerKey(cal); - } + /* + * public void selectFirst(int num) { + * + * int j=0; Calendar cal = times.firstKey(); while ( cal != null ) { if ( + * j++ < num ) times.put(cal, true); else times.put(cal, false); + * + * cal = times.higherKey( cal ); } } + * + * public void selectLast(int num) { + * + * int j=0; Calendar cal = times.lastKey(); while ( cal != null ) { if ( j++ + * < num ) times.put(cal, true); else times.put(cal, false); + * + * cal = times.lowerKey( cal ); } + * + * } + */ - /** - * Returns the available time just after the specified time - * @param cal - * @return - */ - public Calendar getNextTime(Calendar cal) { - return times.higherKey(cal); - } + /** + * Returns the first selected time in the list + */ + public Calendar getFirstSelected() { - /** - * Toggles the "select" indicator for the given time - * @param cal - */ - public void toggle(Calendar cal) { - if ( times.containsKey(cal) ) { - times.put( cal, !times.get(cal) ); - } - } + Map.Entry entry = times.firstEntry(); + while (entry != null) { + if (entry.getValue()) + return entry.getKey(); + entry = times.higherEntry(entry.getKey()); + } + return null; + } - /** - * Returns the number of selected data times - * @return - */ - public int numSelected() { - int num = 0; - for ( Boolean val : times.values() ) { - if ( val ) num++; - } - return num; - } + /** + * Returns the last selected time in the list + * + * @return + */ + public Calendar getLastSelected() { - /** - * Marks the given time as selected - * @param cal - */ - public void select(Calendar cal) { - if ( times.containsKey(cal) ) times.put(cal, true); - } + Map.Entry entry = times.lastEntry(); + while (entry != null) { + if (entry.getValue()) + return entry.getKey(); + entry = times.lowerEntry(entry.getKey()); + } + return null; + } - /** - * Marks the given time as not selected - * @param cal - */ - public void deselect(Calendar cal) { - if ( times.containsKey(cal) ) times.put(cal, false); - } + /** + * Returns the available time just before the specified time + * + * @param cal + * @return + */ + public Calendar getPreviousTime(Calendar cal) { + return times.lowerKey(cal); + } - /** - * Returns the number of available times in the list - * @return - */ - public int getSize() { - return times.size(); - } + /** + * Returns the available time just after the specified time + * + * @param cal + * @return + */ + public Calendar getNextTime(Calendar cal) { + return times.higherKey(cal); + } - /** - * Adds or removes times from the end of the selected list until the specified - * number of times (numFrames) is selected. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - public void appendTimes(int numFrames, int skip) { - - if ( numFrames > numSelected() ) { - if ( numSelected() == 0 ) select(getFirstTime()); - addToLast( numFrames, skip ); - if ( numFrames > numSelected() ) { - addToFirst( numFrames, skip ); - } - } - else if ( numFrames < numSelected() ) { - removeFromLast( numFrames, skip); - } - - } + /** + * Toggles the "select" indicator for the given time + * + * @param cal + */ + public void toggle(Calendar cal) { + if (times.containsKey(cal)) { + times.put(cal, !times.get(cal)); + } + } - /** - * Adds times to the end of the selected list until the specified - * number of times (numFrames) is selected. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - private void addToLast(int numFrames, int skip) { + /** + * Returns the number of selected data times + * + * @return + */ + public int numSelected() { + int num = 0; + for (Boolean val : times.values()) { + if (val) + num++; + } + return num; + } - while ( numSelected() < numFrames ) { - - Calendar cal = getLastSelected(); - for ( int j=0; j <= skip; j++ ) { - cal = getNextTime(cal); - if ( cal == null) return; - } - select(cal); - - } - - } + /** + * Marks the given time as selected + * + * @param cal + */ + public void select(Calendar cal) { + if (times.containsKey(cal)) + times.put(cal, true); + } - /** - * Removes times from the end of the selected list until the specified - * number of times (numFrames) is selected. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - private void removeFromLast(int numFrames, int skip) { + /** + * Marks the given time as not selected + * + * @param cal + */ + public void deselect(Calendar cal) { + if (times.containsKey(cal)) + times.put(cal, false); + } - int count = numSelected(); - while ( count > numFrames ) { - Calendar cal = getLastSelected(); - deselect(cal); - count = numSelected(); - } - } + /** + * Returns the number of available times in the list + * + * @return + */ + public int getSize() { + return times.size(); + } - /** - * Adds or removes times from the beginning of the selected list until the specified - * number of times (numFrames) is selected. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - public void prependTimes(int numFrames, int skip) { + /** + * Adds or removes times from the end of the selected list until the + * specified number of times (numFrames) is selected. The skip factor is + * used to skip a specific number of times between each selected time. + * + * @param numFrames + * @param skip + */ + public void appendTimes(int numFrames, int skip) { - if ( numFrames > numSelected() ) { - if ( numSelected() == 0 ) select(getLastTime()); - addToFirst( numFrames, skip ); - if ( numFrames > numSelected() ) { - addToLast( numFrames, skip ); - } - } - else if ( numFrames < numSelected() ) { - removeFromFirst( numFrames, skip); - } - - } + if (numFrames > numSelected()) { + if (numSelected() == 0) + select(getFirstTime()); + addToLast(numFrames, skip); + if (numFrames > numSelected()) { + addToFirst(numFrames, skip); + } + } else if (numFrames < numSelected()) { + removeFromLast(numFrames, skip); + } - /** - * Adds times to the beginning of the selected list until the specified - * number of times (numFrames) is selected. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - private void addToFirst(int numFrames, int skip) { + } - while ( numSelected() < numFrames ) { - - Calendar cal = getFirstSelected(); - for ( int j=0; j <= skip; j++ ) { - cal = getPreviousTime(cal); - if ( cal == null) return; - } - select(cal); - - } - } + /** + * Adds times to the end of the selected list until the specified number of + * times (numFrames) is selected. The skip factor is used to skip a specific + * number of times between each selected time. + * + * @param numFrames + * @param skip + */ + private void addToLast(int numFrames, int skip) { - /** - * Removes times from the beginning of the selected list until the specified - * number of times (numFrames) is selected. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - private void removeFromFirst(int numFrames, int skip) { - - int count = numSelected(); - while ( count > numFrames ) { - Calendar cal = getFirstSelected(); - deselect(cal); - count = numSelected(); - } - } + while (numSelected() < numFrames) { - /** - * Updates the selected times in the given time range. The skip factor is used to skip - * a specific number of times between each selected time. - * @param numFrames - * @param skip - */ - public void updateRange(Calendar first, Calendar second, int skip) { + Calendar cal = getLastSelected(); + for (int j = 0; j <= skip; j++) { + cal = getNextTime(cal); + if (cal == null) + return; + } + select(cal); - int j=0, loc1=0, loc2=0; - - deselectAll(); - - for ( Calendar cal : times.keySet() ) { - if ( cal.equals(first) ) loc1 = j; - if ( cal.equals(second) ) loc2 = j; - j++; - } - - int avail = Math.abs(loc2 -loc1) + 1; - int num = avail / (skip+1); - if ( num * (skip + 1) < avail ) num++; + } - if ( first.before(second) ) { - select(first); - addToLast( num, skip); - } - else if ( first.after(second) ) { - select(first); - addToFirst( num, skip); - } - else { - select(first); - } - - } + } - /** - * Marks all times in the list as not selected - */ - public void deselectAll() { - for ( Calendar cal : times.keySet() ) { - deselect(cal); - } - } + /** + * Removes times from the end of the selected list until the specified + * number of times (numFrames) is selected. The skip factor is used to skip + * a specific number of times between each selected time. + * + * @param numFrames + * @param skip + */ + private void removeFromLast(int numFrames, int skip) { + + int count = numSelected(); + while (count > numFrames) { + Calendar cal = getLastSelected(); + deselect(cal); + count = numSelected(); + } + } + + /** + * Adds or removes times from the beginning of the selected list until the + * specified number of times (numFrames) is selected. The skip factor is + * used to skip a specific number of times between each selected time. + * + * @param numFrames + * @param skip + */ + public void prependTimes(int numFrames, int skip) { + + if (numFrames > numSelected()) { + if (numSelected() == 0) + select(getLastTime()); + addToFirst(numFrames, skip); + if (numFrames > numSelected()) { + addToLast(numFrames, skip); + } + } else if (numFrames < numSelected()) { + removeFromFirst(numFrames, skip); + } + + } + + /** + * Adds times to the beginning of the selected list until the specified + * number of times (numFrames) is selected. The skip factor is used to skip + * a specific number of times between each selected time. + * + * @param numFrames + * @param skip + */ + private void addToFirst(int numFrames, int skip) { + + while (numSelected() < numFrames) { + + Calendar cal = getFirstSelected(); + for (int j = 0; j <= skip; j++) { + cal = getPreviousTime(cal); + if (cal == null) + return; + } + select(cal); + + } + } + + /** + * Removes times from the beginning of the selected list until the specified + * number of times (numFrames) is selected. The skip factor is used to skip + * a specific number of times between each selected time. + * + * @param numFrames + * @param skip + */ + private void removeFromFirst(int numFrames, int skip) { + + int count = numSelected(); + while (count > numFrames) { + Calendar cal = getFirstSelected(); + deselect(cal); + count = numSelected(); + } + } + + /** + * Updates the selected times in the given time range. The skip factor is + * used to skip a specific number of times between each selected time. + * + * @param numFrames + * @param skip + */ + public void updateRange(Calendar first, Calendar second, int skip) { + + int j = 0, loc1 = 0, loc2 = 0; + + deselectAll(); + + for (Calendar cal : times.keySet()) { + if (cal.equals(first)) + loc1 = j; + if (cal.equals(second)) + loc2 = j; + j++; + } + + int avail = Math.abs(loc2 - loc1) + 1; + int num = avail / (skip + 1); + if (num * (skip + 1) < avail) + num++; + + if (first.before(second)) { + select(first); + addToLast(num, skip); + } else if (first.after(second)) { + select(first); + addToFirst(num, skip); + } else { + select(first); + } + + } + + /** + * Marks all times in the list as not selected + */ + public void deselectAll() { + for (Calendar cal : times.keySet()) { + deselect(cal); + } + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java index edf260957d..5a8e9bc26f 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/createRbd/CreateRbdControl.java @@ -10,6 +10,7 @@ import gov.noaa.nws.ncep.viz.common.display.INcPaneID; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; import gov.noaa.nws.ncep.viz.common.display.NcDisplayName; import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.resourceManager.timeline.GraphTimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl.IDominantResourceChangedListener; import gov.noaa.nws.ncep.viz.resourceManager.ui.createRbd.ResourceSelectionControl.IResourceSelectedListener; @@ -139,7 +140,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 10/22/2013 #1043 Greg Hull setSelectedResource() if rsc sel dlg is already up. * 11/25/2013 #1079 Greg Hull adjust size/font of area toolbar based on the text * 05/07/2014 TTR991 D. Sushon if a different NCP editor is selected, the CreateRDB tab should now adjust. - * + * 05/29/2014 #1131 qzhou Added NcDisplayType + * Modified creating new timelineControl in const and updateGUI *
* * @author ghull @@ -259,6 +261,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { private final String ImportFromSPF = "From SPF..."; + private Group timeline_grp; + // private final String[] StandardZoomLevels = {"1", // "1.5","2","3","5","7.5","10","15","20","30"}; @@ -305,7 +309,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { createRBDGroup(); - Group timeline_grp = new Group(sash_form, SWT.SHADOW_NONE); + timeline_grp = new Group(sash_form, SWT.SHADOW_NONE); timeline_grp.setText("Select Timeline"); gd = new GridData(); gd.grabExcessHorizontalSpace = true; @@ -316,13 +320,21 @@ public class CreateRbdControl extends Composite implements IPartListener2 { timeline_grp.setLayout(new GridLayout()); - timelineControl = new TimelineControl(timeline_grp); + if (mngr.getRbdType().equals(NcDisplayType.GRAPH_DISPLAY)) { + timelineControl = (GraphTimelineControl) new GraphTimelineControl( + timeline_grp); + } else { + timelineControl = new TimelineControl(timeline_grp); + } timelineControl .addDominantResourceChangedListener(new IDominantResourceChangedListener() { @Override public void dominantResourceChanged( AbstractNatlCntrsRequestableResourceData newDomRsc) { + // System.out.println("**createRbd " + // + rbdMngr.isAutoUpdate() + " " + // + newDomRsc.isAutoUpdateable()); if (newDomRsc == null) { auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); auto_update_btn.setEnabled(false); @@ -482,7 +494,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { disp_type_combo.setItems(new String[] { NcDisplayType.NMAP_DISPLAY.getName(), NcDisplayType.NTRANS_DISPLAY.getName(), - NcDisplayType.SOLAR_DISPLAY.getName() }); + NcDisplayType.SOLAR_DISPLAY.getName(), + NcDisplayType.GRAPH_DISPLAY.getName() }); disp_type_lbl = new Label(rbd_grp, SWT.None); disp_type_lbl.setText("RBD Type"); @@ -784,7 +797,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { edit_span_btn.setLayoutData(form_data); edit_span_btn.setEnabled(false); - // seld_rscs_grp.pack(true); + seld_rscs_grp.pack(true); return seld_rscs_grp; } @@ -1106,7 +1119,7 @@ public class CreateRbdControl extends Composite implements IPartListener2 { // if replacing existing resources, get the selected // resources // (For now just replace the 1st if more than one selected.) - // + if (replace) { StructuredSelection sel_elems = (StructuredSelection) seld_rscs_lviewer .getSelection(); @@ -1876,7 +1889,42 @@ public class CreateRbdControl extends Composite implements IPartListener2 { selectPane(rbdMngr.getSelectedPaneId()); - timelineControl.clearTimeline(); + // timelineControl.clearTimeline(); + + // create new timelineControl if is Graph + timelineControl.dispose(); + + if (rbdMngr.getRbdType().equals(NcDisplayType.GRAPH_DISPLAY)) + + timelineControl = (GraphTimelineControl) new GraphTimelineControl( + timeline_grp); + else + timelineControl = new TimelineControl(timeline_grp); + + timelineControl + .addDominantResourceChangedListener(new IDominantResourceChangedListener() { + @Override + public void dominantResourceChanged( + AbstractNatlCntrsRequestableResourceData newDomRsc) { + // System.out.println("**createRbd2 " + // + rbdMngr.isAutoUpdate() + " " + // + newDomRsc.isAutoUpdateable()); + if (newDomRsc == null) { + auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); + auto_update_btn.setEnabled(false); + } else if (newDomRsc.isAutoUpdateable()) { + auto_update_btn.setEnabled(true); + // auto_update_btn.setSelection( + // rbdMngr.isAutoUpdate() );top_comp + auto_update_btn.setSelection(true); + } else { + auto_update_btn.setSelection(false); + auto_update_btn.setEnabled(false); + } + } + }); + + // timelineControl.setTimeMatcher(new NCTimeMatcher()); INcPaneLayout paneLayout = rbdMngr.getPaneLayout(); @@ -1906,6 +1954,8 @@ public class CreateRbdControl extends Composite implements IPartListener2 { auto_update_btn.setSelection(false); auto_update_btn.setEnabled(false); } + + shell.pack(); } // TODO : we could have the pane buttons indicate whether @@ -2815,4 +2865,4 @@ public class CreateRbdControl extends Composite implements IPartListener2 { public void partInputChanged(IWorkbenchPartReference partRef) { // Auto-generated method stub } -} +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java index 0f23e9534d..7e0d865465 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/loadRbd/LoadRbdControl.java @@ -3,10 +3,13 @@ package gov.noaa.nws.ncep.viz.resourceManager.ui.loadRbd; //import gov.noaa.nws.ncep.viz.common.EditorManager; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; +import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.resourceManager.timeline.GraphTimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.timeline.TimelineControl; import gov.noaa.nws.ncep.viz.resourceManager.ui.createRbd.CreateRbdControl; import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; import gov.noaa.nws.ncep.viz.resources.manager.AbstractRBD; +import gov.noaa.nws.ncep.viz.resources.manager.GraphRBD; import gov.noaa.nws.ncep.viz.resources.manager.ResourceBndlLoader; import gov.noaa.nws.ncep.viz.resources.manager.SpfsManager; import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; @@ -162,6 +165,8 @@ public class LoadRbdControl extends Composite { private EditRbdDialog editRbdDlg = null; + private Group timeline_grp; + public LoadRbdControl(Composite parent) throws VizException { super(parent, SWT.NONE); shell = parent.getShell(); @@ -315,7 +320,7 @@ public class LoadRbdControl extends Composite { fd.left = new FormAttachment(auto_update_btn, 0, SWT.LEFT); geo_sync_panes.setLayoutData(fd); - Group timeline_grp = new Group(sash_form, SWT.SHADOW_NONE); + timeline_grp = new Group(sash_form, SWT.SHADOW_NONE); timeline_grp.setText("Select Timeline"); fd = new FormData(); fd.top = new FormAttachment(0, 5); @@ -326,7 +331,15 @@ public class LoadRbdControl extends Composite { timeline_grp.setLayout(new GridLayout()); - timelineControl = new TimelineControl(timeline_grp); + if (!seldRbdsList.isEmpty() + && seldRbdsList.get(0).getDisplayType() + .equals(NcDisplayType.GRAPH_DISPLAY)) { // .getRbdName().equals("Graph")) + // { + timelineControl = new GraphTimelineControl(timeline_grp); + System.out.println("HERE"); + } else { + timelineControl = new TimelineControl(timeline_grp);// quan + } sash_form.setWeights(new int[] { 3, 2 }); @@ -690,14 +703,102 @@ public class LoadRbdControl extends Composite { seldRbdsList.clear(); AbstractRBD rbdSel = null; + // INcPaneLayout paneLayout = rbdMngr.getPaneLayout(); + // + // // set the list of available resources for the timeline + // for (int paneIndx = 0; paneIndx < paneLayout.getNumberOfPanes(); + // paneIndx++) { + // for (ResourceSelection rscSel : rbdMngr + // .getRscsForPane((NcPaneID) paneLayout + // .createPaneId(paneIndx))) { + // + // if (rscSel.getResourceData() instanceof + // AbstractNatlCntrsRequestableResourceData) { + // timelineControl + // .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) + // rscSel + // .getResourceData()); + // } + // } + // } + while (sel_iter.hasNext()) { rbdSel = (AbstractRBD) sel_iter.next(); - // if( rbdSel.getTimeMatcher().getDominantResource() == null ) { + // if (rbdSel.getTimeMatcher().getDominantResource() == null) { // System.out.println("Dominant Resource is null?"); + // } else { + // rbdSel.getTimeMatcher().loadTimes(true); // } - // else { - // rbdSel.getTimeMatcher().loadTimes(); - // } + + // timelineControl.dispose(); + if (rbdSel instanceof GraphRBD) { + updateGUI(rbdSel); + // rbdSel.getDisplayType().equals(NcDisplayType.GRAPH_DISPLAY)) + // {// + // timelineControl = (GraphTimelineControl) new + // GraphTimelineControl( + // timeline_grp); + // + // timelineControl + // .addDominantResourceChangedListener(new + // IDominantResourceChangedListener() { + // @Override + // public void dominantResourceChanged( + // AbstractNatlCntrsRequestableResourceData newDomRsc) { + // if (newDomRsc == null) { + // // auto_update_btn.setSelection(rbdMngr.isAutoUpdate()); + // auto_update_btn.setEnabled(false); + // } else if (newDomRsc.isAutoUpdateable()) { + // auto_update_btn.setEnabled(true); + // // auto_update_btn.setSelection( + // // rbdMngr.isAutoUpdate() ); + // auto_update_btn.setSelection(true); + // } else { + // auto_update_btn.setSelection(false); + // auto_update_btn.setEnabled(false); + // } + // } + // }); + // + // // set the list of available resources for the timeline + // // INcPaneLayout paneLayout = rbdSel.getPaneLayout(); + // // + // // for (int paneIndx = 0; paneIndx < + // paneLayout.getNumberOfPanes(); + // // paneIndx++) { + // // for (ResourceSelection rscSel : rbdMngr + // // .getRscsForPane((NcPaneID) paneLayout + // // .createPaneId(paneIndx))) { + // // + // // if (rbdSel.getrscSel.getResourceData() instanceof + // // AbstractNatlCntrsRequestableResourceData) { + // // timelineControl + // // + // .addAvailDomResource((AbstractNatlCntrsRequestableResourceData) + // // rscSel + // // .getResourceData()); + // // } + // // } + // // } + // + // NCTimeMatcher timeMatcher = rbdSel.getTimeMatcher(); + // // ArrayList list = new ArrayList(); + // // DataTime time = timeMatcher.getRefTime(); + // // System.out.println("***time " + time); + // // Calendar cal = (Calendar) time.getValidTime(); + // // for (int i = 0; i < 720; i++) { + // // cal.add(Calendar.MINUTE, -1); + // // list.add(new DataTime((Calendar) cal.clone())); + // // } + // // timeMatcher.setFrameTimes(list); + // + // timelineControl.setTimeMatcher(timeMatcher); + // timelineControl.addAvailDomResource(timeMatcher + // .getDominantResource()); + + } else { + timelineControl = new TimelineControl(timeline_grp); + } rbdSel.initTimeline(); seldRbdsList.add(rbdSel); @@ -998,4 +1099,41 @@ public class LoadRbdControl extends Composite { editRbdDlg = null; } + + public void updateGUI(final AbstractRBD rbdSel) { + if (rbdSel instanceof GraphRBD) { + timelineControl.dispose(); + // shell.pack(); + timelineControl = (GraphTimelineControl) new GraphTimelineControl( + timeline_grp); + + // timelineControl + // .addDominantResourceChangedListener(new + // IDominantResourceChangedListener() { + // @Override + // public void dominantResourceChanged( + // AbstractNatlCntrsRequestableResourceData newDomRsc) { + // if (newDomRsc == null) { + // auto_update_btn.setSelection(rbdSel + // .isAutoUpdate()); + // auto_update_btn.setEnabled(false); + // } else if (newDomRsc.isAutoUpdateable()) { + // auto_update_btn.setEnabled(true); + // // auto_update_btn.setSelection( + // // rbdMngr.isAutoUpdate() );top_comp + // auto_update_btn.setSelection(true); + // } else { + // auto_update_btn.setSelection(false); + // auto_update_btn.setEnabled(false); + // } + // } + // }); + // + // timelineControl.setTimeMatcher(rbdSel.getTimeMatcher()); + // timelineControl.addAvailDomResource(rbdSel.getTimeMatcher() + // .getDominantResource()); + // shell.pack(); + } + + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/manageResources/EditResourceTypeComp.java b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/manageResources/EditResourceTypeComp.java index 6aaaade833..32b559aa27 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/manageResources/EditResourceTypeComp.java +++ b/ncep/gov.noaa.nws.ncep.viz.resourceManager/src/gov/noaa/nws/ncep/viz/resourceManager/ui/manageResources/EditResourceTypeComp.java @@ -1,7 +1,6 @@ package gov.noaa.nws.ncep.viz.resourceManager.ui.manageResources; import gov.noaa.nws.ncep.viz.common.StringListAdapter; -import gov.noaa.nws.ncep.viz.localization.NcPathManager; import gov.noaa.nws.ncep.viz.localization.NcPathManager.NcPathConstants; import gov.noaa.nws.ncep.viz.resourceManager.ui.manageResources.ManageResourceControl.IEditResourceComposite; import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData.TimeMatchMethod; @@ -40,13 +39,10 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; -import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.localization.LocalizationFile; -import com.raytheon.uf.common.time.BinOffset; import com.raytheon.uf.viz.core.exception.VizException; - /** * * @@ -69,1101 +65,1169 @@ import com.raytheon.uf.viz.core.exception.VizException; * 04/11/13 #864 Greg Hull new TimelineGenMethods and EVENT TimeMatchMthd * 06/10/13 #997 Greg Hull Copy AttrSets with RDs * 07/18/13 #1011 Greg Hull Add ALL_DATA as a frameSpan option. - * + * 06/26/2014 #1136 Quan Zhou Disable dfltNumFramesLbl & dfltNumFramesSpnr when TIMESERIES * * - * @author + * @author * @version 1 */ class EditResourceTypeComp extends Composite implements IEditResourceComposite { - ResourceDefnsMngr rscDefnMngr; - ManageResourceControl mngrControl; // the parent composite - - ResourceName seldRscName=null; - ResourceDefinition seldRscDefn; - - Text rscTypeTxt; - Spinner dfltNumFramesSpnr; - Spinner dfltTimeRangeDaysSpnr; - Spinner dfltTimeRangeHrsSpnr; -// Spinner timeIntervalSpnr; - Label frameIntLbl; // either 'Frame Span' or 'Default Frame Interval' - Combo frameSpanCombo; - Label minsLbl2, minsLbl3; - Group timelineGenMthdGrp; - Button useFrameIntrvlBtn; - Button useDataTimesBtn; - Button useFcstDataTimesBtn; - Button useManualTimelineBtn; - Button useFcstFrameIntrvlBtn; -// Combo timelineGenMethodCombo; - Combo timeMatchMethodCombo; - Button binDataBtn; - Spinner binStartIntrvlSpnr; - Spinner binEndIntrvlSpnr; - Label startLbl, endLbl; - Text editParamsTxt; - Label editParamsLbl; - - Text filterLabelsTxt; - Label filterLabelsLbl; - - Text subTypeGenTxt; - Label subTypeGenLbl; - - Text rscImplTxt; - - Button newTypeBtn; - Button saveTypeBtn; - Button cancelBtn; - - String availFrameSpanStrings[] = { //"N/A", - "1 min", "2 mins", "5 mins", "10 mins", "15 mins", "20 mins", "30 mins", - "1 hr", "90 mins", "2 hrs", "3 hrs", "6 hrs", "12 hrs", "24 hrs", "All Data" }; - - int availFrameSpanMins[] = { //0, - 1, 2, 5, 10, 15, 20, 30, 60, 90, 120, 180, 360, 720, 1440, Integer.MAX_VALUE }; - - public EditResourceTypeComp( Composite parent, int style, - ManageResourceControl mgrCtl) { - super( parent, style ); - Composite top_form = this; - - FormData fd = new FormData(); - fd.top = new FormAttachment( 0, 12 ); // offset from sash so the title shows up - fd.left = new FormAttachment( 0, 0 ); - fd.right = new FormAttachment( 100, 0 ); - fd.bottom = new FormAttachment( 100, 0 ); - top_form.setLayoutData(fd); - - setLayoutData( fd ); - - top_form.setLayout( new FormLayout() ); - - mngrControl = mgrCtl; - rscDefnMngr = mngrControl.getRscDefnMngr(); - - rscTypeTxt = new Text( top_form, SWT.SINGLE | SWT.BORDER ); - rscTypeTxt.setText( "" ); - - fd = new FormData(); - fd.width = 150; - fd.top = new FormAttachment( 0, 30 ); - fd.left = new FormAttachment( 0, 15 ); - rscTypeTxt.setLayoutData( fd ); - - Label rscTypeLbl = new Label( top_form, SWT.NONE ); - rscTypeLbl.setText("Resource Type"); - fd = new FormData(); - fd.bottom = new FormAttachment( rscTypeTxt, -3, SWT.TOP ); - fd.left = new FormAttachment( rscTypeTxt, 0, SWT.LEFT ); - rscTypeLbl.setLayoutData( fd ); - - dfltNumFramesSpnr = new Spinner( top_form, SWT.BORDER ); - fd = new FormData(); - fd.top = new FormAttachment( rscTypeTxt, 0, SWT.TOP ); - fd.left = new FormAttachment( rscTypeTxt, 35, SWT.RIGHT ); - dfltNumFramesSpnr.setLayoutData( fd ); - - Label dfltNumFramesLbl = new Label( top_form, SWT.NONE ); - dfltNumFramesLbl.setText("Num Frames");//Default Num\nFrames"); - fd = new FormData(); - fd.bottom = new FormAttachment( dfltNumFramesSpnr, -3, SWT.TOP ); - fd.left = new FormAttachment( dfltNumFramesSpnr, 0, SWT.LEFT ); //rscTypeTxt, 20, SWT.RIGHT ); - dfltNumFramesLbl.setLayoutData( fd ); - - dfltNumFramesSpnr.setMinimum(1); - dfltNumFramesSpnr.setMaximum(999); - dfltNumFramesSpnr.setDigits(0); - dfltNumFramesSpnr.setIncrement(1); - dfltNumFramesSpnr.setTextLimit(4); - - editParamsTxt = new Text( top_form, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL ); - fd = new FormData(); - fd.height = 120; - fd.left = new FormAttachment( 45, 0); - fd.top = new FormAttachment( dfltNumFramesSpnr, 0, SWT.TOP ); - fd.right = new FormAttachment( 100, -10 ); -// fd.bottom = new FormAttachment( 65, 0 ); - editParamsTxt.setLayoutData( fd ); - - editParamsLbl = new Label( top_form, SWT.NONE ); - editParamsLbl.setText("Edit Parameters"); // add the implementaion later - fd = new FormData(); - fd.bottom = new FormAttachment( editParamsTxt, -3, SWT.TOP ); - fd.left = new FormAttachment( editParamsTxt, 0, SWT.LEFT ); - fd.right = new FormAttachment( editParamsTxt, 0, SWT.RIGHT ); - editParamsLbl.setLayoutData( fd ); - - - filterLabelsTxt = new Text( top_form, SWT.SINGLE | SWT.BORDER ); //| SWT.V_SCROLL | SWT.H_SCROLL ); - fd = new FormData(); - fd.height = 20; - fd.left = new FormAttachment( editParamsTxt, 0, SWT.LEFT ); - fd.right = new FormAttachment( editParamsTxt, 0, SWT.RIGHT ); - fd.top = new FormAttachment( editParamsTxt, 40, SWT.BOTTOM ); - filterLabelsTxt.setLayoutData( fd ); - filterLabelsTxt.setToolTipText( "comma-separated labels." ); - - - filterLabelsLbl = new Label( top_form, SWT.NONE ); - filterLabelsLbl.setText("Filterable Labels"); - fd = new FormData(); - fd.bottom = new FormAttachment( filterLabelsTxt, -3, SWT.TOP ); - fd.left = new FormAttachment( filterLabelsTxt, 0, SWT.LEFT ); - // the text will be changed for the localization level so make it wider - fd.right = new FormAttachment( filterLabelsTxt, 0, SWT.RIGHT ); - filterLabelsLbl.setLayoutData( fd ); - - rscImplTxt = new Text( top_form, SWT.SINGLE | SWT.BORDER ); - fd = new FormData(); - fd.width = 150; - fd.left = new FormAttachment( filterLabelsTxt, 0, SWT.LEFT ); - fd.top = new FormAttachment( filterLabelsTxt, 40, SWT.BOTTOM ); - rscImplTxt.setLayoutData( fd ); - rscImplTxt.setToolTipText( rscImplToolTipText ); - rscImplTxt.setBackground( top_form.getBackground() ); - rscImplTxt.setEditable(false); - - Label rscImplLbl = new Label( top_form, SWT.NONE ); - rscImplLbl.setText("Resource Implementation"); - fd = new FormData(); - fd.bottom = new FormAttachment( rscImplTxt, -3, SWT.TOP ); - fd.left = new FormAttachment( rscImplTxt, 0, SWT.LEFT ); - rscImplLbl.setLayoutData( fd ); - - - subTypeGenTxt = new Text( top_form, SWT.SINGLE | SWT.BORDER ); - fd = new FormData(); - fd.width = 140; - fd.left = new FormAttachment( rscImplTxt, 15, SWT.RIGHT ); - fd.top = new FormAttachment( rscImplTxt, 0, SWT.TOP ); - subTypeGenTxt.setLayoutData( fd ); - subTypeGenTxt.setToolTipText( subTypeGenToolTipText ); - subTypeGenTxt.setVisible( false ); - subTypeGenTxt.setBackground( top_form.getBackground() ); - subTypeGenTxt.setEditable(false); - - subTypeGenLbl = new Label( top_form, SWT.NONE ); - subTypeGenLbl.setText("Sub-Type Generator(s)"); - fd = new FormData(); - fd.bottom = new FormAttachment( subTypeGenTxt, -3, SWT.TOP ); - fd.left = new FormAttachment( subTypeGenTxt, 0, SWT.LEFT ); - subTypeGenLbl.setLayoutData( fd ); - - - frameSpanCombo = new Combo( top_form, SWT.DROP_DOWN | SWT.READ_ONLY ); - fd = new FormData(); - fd.top = new FormAttachment( rscTypeTxt, 40, SWT.BOTTOM ); - fd.left = new FormAttachment( rscTypeTxt, 0, SWT.LEFT ); - frameSpanCombo.setLayoutData( fd ); - //frameIntervalCombo.setToolTipText( frameIntervalToolTipText ); - frameSpanCombo.setItems( availFrameSpanStrings ); - - frameIntLbl = new Label( top_form, SWT.NONE ); - frameIntLbl.setText("Frame Span"); - fd = new FormData(); - fd.bottom = new FormAttachment( frameSpanCombo, -3, SWT.TOP ); - fd.left = new FormAttachment( frameSpanCombo, 0, SWT.LEFT ); - frameIntLbl.setLayoutData( fd ); - - - dfltTimeRangeDaysSpnr = new Spinner( top_form, SWT.BORDER ); - fd = new FormData(); - fd.top = new FormAttachment( frameSpanCombo, 0, SWT.TOP ); - fd.left = new FormAttachment( frameSpanCombo, 70, SWT.RIGHT ); - dfltTimeRangeDaysSpnr.setLayoutData( fd ); - - Label dfltTimeRangeLbl = new Label( top_form, SWT.NONE ); - dfltTimeRangeLbl.setText("Range (Days/Hrs)"); - fd = new FormData(); - fd.bottom = new FormAttachment( dfltTimeRangeDaysSpnr, -3, SWT.TOP ); - fd.left = new FormAttachment( dfltTimeRangeDaysSpnr, 0, SWT.LEFT ); - dfltTimeRangeLbl.setLayoutData( fd ); - - dfltTimeRangeDaysSpnr.setMinimum(0); - dfltTimeRangeDaysSpnr.setMaximum(999); - dfltTimeRangeDaysSpnr.setDigits(0); - dfltTimeRangeDaysSpnr.setIncrement(1); - dfltTimeRangeDaysSpnr.setTextLimit(4); - dfltTimeRangeDaysSpnr.setPageIncrement(30); - -// Label timeRangeDaysLbl = new Label( top_form, SWT.NONE ); -// timeRangeDaysLbl.setText("Days"); -// fd = new FormData(); -// fd.top = new FormAttachment( dfltTimeRangeDaysSpnr, 3, SWT.TOP ); -// fd.left = new FormAttachment( dfltTimeRangeDaysSpnr, 3, SWT.RIGHT ); -// timeRangeDaysLbl.setLayoutData( fd ); - - dfltTimeRangeHrsSpnr = new Spinner( top_form, SWT.BORDER ); - fd = new FormData(); - fd.top = new FormAttachment( dfltTimeRangeDaysSpnr, 0, SWT.TOP ); - fd.left = new FormAttachment( dfltTimeRangeDaysSpnr, 8, SWT.RIGHT ); - dfltTimeRangeHrsSpnr.setLayoutData( fd ); - - dfltTimeRangeHrsSpnr.setMinimum(0); - dfltTimeRangeHrsSpnr.setMaximum(23); - dfltTimeRangeHrsSpnr.setDigits(0); - dfltTimeRangeHrsSpnr.setIncrement(1); - dfltTimeRangeHrsSpnr.setTextLimit(2); - - // a group composite to force the radio behaviour - timelineGenMthdGrp = new Group( top_form, SWT.SHADOW_NONE ); - timelineGenMthdGrp.setText("Generate Timeline from:"); - fd = new FormData(); - fd.top = new FormAttachment( frameSpanCombo, 20, SWT.BOTTOM ); - fd.left = new FormAttachment( frameSpanCombo, 0, SWT.LEFT ); - timelineGenMthdGrp.setLayoutData( fd ); - - GridLayout gl = new GridLayout(2, false); - gl.horizontalSpacing = 10; - gl.marginWidth = 15; - gl.marginHeight = 10; - timelineGenMthdGrp.setLayout( gl); - - useFcstDataTimesBtn = new Button(timelineGenMthdGrp, SWT.RADIO ); - useFcstDataTimesBtn.setText( "Forecast Hrs From Cycle Time" ); - fd = new FormData(); - GridData gd = new GridData(); - gd.horizontalSpan = 2; - useFcstDataTimesBtn.setLayoutData( gd ); - - useDataTimesBtn = new Button(timelineGenMthdGrp, SWT.RADIO ); - useDataTimesBtn.setText( "Data Times" ); - fd = new FormData(); - useDataTimesBtn.setLayoutData( new GridData() ); - - useFrameIntrvlBtn = new Button(timelineGenMthdGrp, SWT.RADIO ); - useFrameIntrvlBtn.setText( "Frame Interval" );//Time Interval of" ); - useFrameIntrvlBtn.setLayoutData( new GridData() ); - - useManualTimelineBtn = new Button(timelineGenMthdGrp, SWT.RADIO ); - useManualTimelineBtn.setText( "Manual Timeline" ); - fd = new FormData(); - useManualTimelineBtn.setLayoutData( new GridData() ); - - useFcstFrameIntrvlBtn = new Button(timelineGenMthdGrp, SWT.RADIO ); - useFcstFrameIntrvlBtn.setText( "Fcst Frame Interval From Ref. Time" ); - fd = new FormData(); - gd = new GridData(); - gd.horizontalSpan = 2; - useFcstFrameIntrvlBtn.setLayoutData( gd ); - - timeMatchMethodCombo = new Combo( top_form, SWT.DROP_DOWN | SWT.READ_ONLY ); - fd = new FormData(); - fd.top = new FormAttachment( timelineGenMthdGrp, 40, SWT.BOTTOM ); - fd.left = new FormAttachment( timelineGenMthdGrp, 0, SWT.LEFT ); - timeMatchMethodCombo.setLayoutData( fd ); - - Label timeMatchMthdLbl = new Label( top_form, SWT.NONE ); - timeMatchMthdLbl.setText("Time Matching Method"); - fd = new FormData(); - fd.bottom = new FormAttachment( timeMatchMethodCombo, -2, SWT.TOP ); - fd.left = new FormAttachment( timeMatchMethodCombo, 0, SWT.LEFT ); - timeMatchMthdLbl.setLayoutData( fd ); - - - binDataBtn = new Button(top_form, SWT.CHECK ); - binDataBtn.setText( "Enable Binning" ); - fd = new FormData(); - fd.top = new FormAttachment( subTypeGenTxt, 25, SWT.BOTTOM ); - fd.left = new FormAttachment( subTypeGenTxt, 0, SWT.LEFT ); - binDataBtn.setLayoutData( fd ); - binDataBtn.setEnabled( false ); // not implemented yet - - // TODO: Remove the bin offset widgets if the frame Span is sufficient to replace it - binDataBtn.setVisible( false ); - - binStartIntrvlSpnr = new Spinner( top_form, SWT.BORDER ); - fd = new FormData(); - fd.top = new FormAttachment( binDataBtn, 30, SWT.BOTTOM ); - fd.left = new FormAttachment( binDataBtn, 20, SWT.LEFT ); - binStartIntrvlSpnr.setLayoutData( fd ); - - binStartIntrvlSpnr.setMinimum(0); - binStartIntrvlSpnr.setMaximum(60*3); // 3hrs : Is this reasonable? - binStartIntrvlSpnr.setDigits(0); - binStartIntrvlSpnr.setIncrement(1); - binStartIntrvlSpnr.setTextLimit(2); - - startLbl = new Label( top_form, SWT.NONE ); - startLbl.setText("Before"); - fd = new FormData(); - fd.bottom = new FormAttachment( binStartIntrvlSpnr, -2, SWT.TOP ); - fd.left = new FormAttachment( binStartIntrvlSpnr, 0, SWT.LEFT ); - startLbl.setLayoutData( fd ); - - minsLbl2 = new Label( top_form, SWT.NONE ); - minsLbl2.setText("mins"); - fd = new FormData(); - fd.top = new FormAttachment( binStartIntrvlSpnr, 3, SWT.TOP ); - fd.left = new FormAttachment( binStartIntrvlSpnr, 5, SWT.RIGHT ); - minsLbl2.setLayoutData( fd ); - - binEndIntrvlSpnr = new Spinner( top_form, SWT.BORDER ); - fd = new FormData(); - fd.top = new FormAttachment( binStartIntrvlSpnr, 0, SWT.TOP ); - fd.left = new FormAttachment( binStartIntrvlSpnr, 50, SWT.RIGHT ); - binEndIntrvlSpnr.setLayoutData( fd ); - - binEndIntrvlSpnr.setMinimum(0); - binEndIntrvlSpnr.setMaximum(60*3); // 3hrs : Is this reasonable? - binEndIntrvlSpnr.setDigits(0); - binEndIntrvlSpnr.setIncrement(1); - binEndIntrvlSpnr.setTextLimit(2); - - endLbl = new Label( top_form, SWT.NONE ); - endLbl.setText("After"); - fd = new FormData(); - fd.bottom = new FormAttachment( binEndIntrvlSpnr, -2, SWT.TOP ); - fd.left = new FormAttachment( binEndIntrvlSpnr, 0, SWT.LEFT ); - endLbl.setLayoutData( fd ); - - minsLbl3 = new Label( top_form, SWT.NONE ); - minsLbl3.setText("mins"); - fd = new FormData(); - fd.top = new FormAttachment( binEndIntrvlSpnr, 3, SWT.TOP ); - fd.left = new FormAttachment( binEndIntrvlSpnr, 5, SWT.RIGHT ); - minsLbl3.setLayoutData( fd ); - - // Only one of these will be visible at a time - saveTypeBtn = new Button( top_form, SWT.PUSH ); - saveTypeBtn.setText("Save"); - fd = new FormData(); - fd.width = 100; - fd.bottom = new FormAttachment( 100, -10 ); - fd.right = new FormAttachment( 100, -30 ); - saveTypeBtn.setLayoutData( fd ); - - newTypeBtn = new Button( top_form, SWT.PUSH ); - newTypeBtn.setText("Create"); - fd = new FormData(); - fd.width = 100; - fd.bottom = new FormAttachment( 100, -10 ); - fd.right = new FormAttachment( 100, -30 ); - newTypeBtn.setLayoutData( fd ); - - cancelBtn = new Button( top_form, SWT.PUSH ); - cancelBtn.setText( "Cancel"); - fd = new FormData(); - fd.width = 100; - fd.bottom = new FormAttachment( 100, -10 ); - fd.right = new FormAttachment( saveTypeBtn, -20, SWT.LEFT ); - cancelBtn.setLayoutData( fd ); - - - // initialize the combo boxes with selectable items. - // - for( TimeMatchMethod tmm : TimeMatchMethod.values() ) { - timeMatchMethodCombo.add( tmm.toString() ); - } - - ArrayList availRscImplementations = - ResourceExtPointMngr.getInstance().getAvailResources(); - - - rscTypeTxt.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - - String newTextStr = rscTypeTxt.getText().trim(); - - int indx = newTextStr.indexOf( "${" ); - - if( indx != -1 ) { - newTextStr = newTextStr.substring(0,indx-1); - } - - if( newTextStr.isEmpty() ) { - saveTypeBtn.setEnabled( false ); - newTypeBtn.setEnabled( false ); - } - else { - saveTypeBtn.setEnabled( true ); - - // if the name has been changed, the 'save' button acts as a 'Rename' or Save As - // - // disable the New button if the name hasn't been changed. - // - if( seldRscDefn.getResourceDefnName().equals( newTextStr ) ) { - saveTypeBtn.setText("Save" ); - - newTypeBtn.setEnabled( false ); - } - else { - saveTypeBtn.setText("Save As" ); - newTypeBtn.setEnabled( true ); - - // disable the Save button if the new name already exists - String rscType = newTextStr; - - //ResourceDefinition.getResourceType( rscTypeTxt.getText().trim() ); - - if( rscDefnMngr.findResourceDefinition( rscType ) ) { - saveTypeBtn.setEnabled( false ); - } - } - } - } - }); - - useFrameIntrvlBtn.addSelectionListener( new SelectionAdapter() { - public void widgetSelected( SelectionEvent ev ) { -// frameIntervalCombo.setEnabled( useTimeIntrvlBtn.getSelection() ); -// timeIntervalCombo.setVisible( useTimeIntrvlBtn.getSelection() ); -// minsLbl1.setVisible( useTimeIntrvlBtn.getSelection() ); - } - }); - - binDataBtn.addSelectionListener( new SelectionAdapter() { - public void widgetSelected( SelectionEvent ev ) { - binStartIntrvlSpnr.setVisible( binDataBtn.getSelection() ); - binEndIntrvlSpnr.setVisible( binDataBtn.getSelection() ); - startLbl.setVisible( binDataBtn.getSelection() ); - endLbl.setVisible( binDataBtn.getSelection() ); - minsLbl2.setVisible( binDataBtn.getSelection() ); - minsLbl3.setVisible( binDataBtn.getSelection() ); } - }); - - editParamsTxt.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - } - }); - -// subTypeGenTxt.addVerifyListener( new VerifyListener() { -// @Override -// public void verifyText(VerifyEvent event) { -// String text = ((Text) event.widget).getText(); -// String newText = event.text; -// -// if( !text.startsWith("${") || -// !text.endsWith("}" ) ) { -// event.doit = false; -// return; -// } -// } -// }); - - saveTypeBtn.addSelectionListener( new SelectionAdapter() { - public void widgetSelected( SelectionEvent ev ) { - saveResourceDefinition(); - } - }); - - newTypeBtn.addSelectionListener( new SelectionAdapter() { - public void widgetSelected( SelectionEvent ev ) { - createResourceDefinition(); - } - }); - - cancelBtn.addSelectionListener( new SelectionAdapter() { - public void widgetSelected( SelectionEvent ev ) { - mngrControl.editActionCanceled(); - } - }); - } - - @Override - public ResourceName getSelectedResourceName( ) { - return seldRscName; - } - - // TODO : not implemented - @Override - public boolean isModified( ) { - return false; - } - - @Override - public void activate() { - setVisible( true ); - if( getParent() instanceof Group ) { - ((Group)getParent()).setText( getTitle() ); - } - } - - public void copySelectedResource( ResourceName rscName ) { - setSelectedResource( rscName ); - newTypeBtn.setVisible( true ); - saveTypeBtn.setVisible( false ); - rscTypeTxt.setEditable( true ); - rscTypeTxt.setBackground( editParamsTxt.getBackground() ); // set white to indicate editable - - rscTypeTxt.setText( "CopyOf"+rscTypeTxt.getText() ); - rscTypeTxt.setSelection(0, rscTypeTxt.getText().length() ); - rscTypeTxt.setFocus(); - } - - public void editSelectedResource( ResourceName rscName ) { - setSelectedResource( rscName ); - newTypeBtn.setVisible( false ); - saveTypeBtn.setVisible( true ); - - rscTypeTxt.setEditable( false ); - rscTypeTxt.setBackground( getParent().getBackground() ); - } - - public void setSelectedResource( ResourceName rscName ) { - - seldRscName = rscName; - - if( seldRscName.getRscType().isEmpty() ) { - rscTypeTxt.setText(""); - saveTypeBtn.setEnabled( false ); - } - else { - saveTypeBtn.setEnabled( false ); - - seldRscDefn = new ResourceDefinition( rscDefnMngr.getResourceDefinition( seldRscName ) ); - - if( seldRscDefn == null ) { // ???? - System.out.println("Unable to get Resource Defn for:"+seldRscName ); - return; - } - - String rscTypeGen = seldRscDefn.getRscTypeGenerator(); - - if( rscTypeGen != null && !rscTypeGen.isEmpty() ) { - rscTypeTxt.setText( seldRscName.getRscType() + - ":${"+ rscTypeGen + "}"); - } - else { - rscTypeTxt.setText( seldRscName.getRscType() ); - } - - // set the frame count - int numFrames = seldRscDefn.getDfltFrameCount(); - dfltNumFramesSpnr.setSelection( numFrames ); - - // if we let any resource select Manual timeline then we need another way to - // specify 'Event-type' resources .... - TimelineGenMethod timelineMthd = seldRscDefn.getTimelineGenMethod(); - - useDataTimesBtn.setEnabled( true ); - useFrameIntrvlBtn.setEnabled( true ); - useFcstDataTimesBtn.setEnabled( true ); - useManualTimelineBtn.setEnabled( true ); - useFcstFrameIntrvlBtn.setEnabled( false ); - - useDataTimesBtn.setSelection( false ); - useFcstDataTimesBtn.setSelection( false ); - useFrameIntrvlBtn.setSelection( false ); - useManualTimelineBtn.setSelection( false ); - useFcstFrameIntrvlBtn.setSelection( false ); - - if( timelineMthd == TimelineGenMethod.USE_DATA_TIMES ) { - useDataTimesBtn.setSelection( true ); - } - else if( timelineMthd == TimelineGenMethod.USE_CYCLE_TIME_FCST_HOURS ) { - useFcstDataTimesBtn.setSelection( true ); - } - else if( timelineMthd == TimelineGenMethod.USE_FRAME_INTERVAL ) { - useFrameIntrvlBtn.setSelection( true ); - } - else if( timelineMthd == TimelineGenMethod.USE_MANUAL_TIMELINE ) { - useManualTimelineBtn.setSelection( true ); - } - // just for TAF for now. So don't let the user change it and just show - else if( timelineMthd == TimelineGenMethod.USE_FCST_FRAME_INTERVAL_FROM_REF_TIME ) { - useFcstFrameIntrvlBtn.setEnabled( true ); - useFcstFrameIntrvlBtn.setSelection( true ); - - useFrameIntrvlBtn.setEnabled( false ); - useDataTimesBtn.setEnabled( false ); - useFcstDataTimesBtn.setEnabled( false ); - useManualTimelineBtn.setEnabled( false ); - } - - // if this is an event type resource; modify the - // timeMatchMthd, frameInterval and timelineGeneration selections - timeMatchMethodCombo.removeAll(); - frameSpanCombo.removeAll(); - - if( seldRscDefn.getTimeMatchMethod() == TimeMatchMethod.EVENT ) { - - useDataTimesBtn.setSelection( false ); // sanity check since - useFrameIntrvlBtn.setSelection( false ); // all event resources should - useManualTimelineBtn.setSelection( true ); // be set to MANUAL anyway - - useDataTimesBtn.setEnabled( false ); - useFcstDataTimesBtn.setEnabled( false ); - useFrameIntrvlBtn.setEnabled( false ); - - // For event resources, only EXACT is meaningful - timeMatchMethodCombo.add( TimeMatchMethod.EVENT.toString() ); - timeMatchMethodCombo.select(0); - - // for Event resources the frameSpan is the default Frame Interval - frameIntLbl.setText("Dflt Frame Interval"); -// frameSpanCombo.add( "N/A" ); -// frameSpanCombo.select(0); - frameSpanCombo.setItems( availFrameSpanStrings ); - frameSpanCombo.setToolTipText("For this Event-Type resource the Default Frame Interval is \n"+ - "used to set the initial Frame Interval for a Manual timeline." ); - - int frameSpan = seldRscDefn.getFrameSpan(); - frameSpanCombo.deselectAll(); - - for( int i=0; i filtersList=null; - try { - filtersList = strListAdptr.unmarshal( filterLabelsTxt.getText().trim() ); - } - catch (Exception e1) { - MessageDialog warnDlg = new MessageDialog( getShell(), - "Resource", null, - "Unable to parse the filters string.\n"+ - "This should be a list of comma separated strings.", - MessageDialog.WARNING, new String[]{"OK"}, 0); - warnDlg.open(); - } - - ResourceDefinitionFilter rdFilt = - rscDefnMngr.getResourceDefnFilter( seldRscDefn.getResourceDefnName() ); - - rdFilt = new ResourceDefinitionFilter( - newRscDefn.getResourceDefnName(), rdFilt.getIsEnabled(), filtersList, - LocalizationLevel.USER ); - - rscDefnMngr.setResourceDefnFilters( rdFilt ); - - try { - rscDefnMngr.saveResourceDefnFiltersFile(); - } - catch (VizException e1) { - MessageDialog errDlg = new MessageDialog( getShell(), - "Resource", null, "Error saving a new Resource Filters File:\n"+ - e1.getMessage(), MessageDialog.ERROR, new String[]{"OK"}, 0); - errDlg.open(); - } - - // if attrSetGroups apply then we will just create 1 standard attrSetGroup with nothing in - // it. The user will need to edit this later. - // TODO : allow the user to copy all (or some?) of the attributeSetGroups from the - // original rscDefn. - - String newLocFilename = seldRscDefn.getLocalizationFile().getName(); - - // peal off the filename and last directory of the same name - // and replace with a path and filename based on the new name - newLocFilename = newLocFilename.substring( 0, - newLocFilename.lastIndexOf(File.separator) ); - newLocFilename = newLocFilename.substring( 0, - newLocFilename.lastIndexOf(File.separator)+1 ) + - rscTypeName + File.separator + rscTypeName + ".xml"; - - newRscDefn.setLocalizationFile( null ); - newRscDefn.setLocalizationName( newLocFilename ); - - //seldRscDefn.setResourceDefnName( rscTypeName ); -// String origRscType = seldRscDefn.getResourceDefnName(); - - try { - rscDefnMngr.saveResourceDefn( newRscDefn ); - -// create a new attrSetGroup - if( newRscDefn.applyAttrSetGroups() ) { - if( !newRscDefn.isPgenResource() ) { - AttrSetGroup asg = new AttrSetGroup(); - asg.setResource( newRscDefn.getResourceDefnName() ); - asg.setAttrSetGroupName("standard"); - - rscDefnMngr.saveAttrSetGroup( asg ); - } - } - // Copy all of the attr sets - else { - List availAttrSets = rscDefnMngr.getAttrSetsForResource(seldRscName, false ); - - for( AttributeSet attrSet : availAttrSets ) { - try { - FileReader fr = new FileReader( attrSet.getFile().getFile() ); - char[] attrsSetStr = new char[(int) attrSet.getFile().getFile().length()]; - fr.read(attrsSetStr); - fr.close(); - - rscDefnMngr.saveAttrSet(newRscDefn, attrSet.getName(), new String( attrsSetStr ) ); - - } - catch (FileNotFoundException fnf ) { - throw new VizException( "file not found for default attr set."); - } - catch (IOException ioe ) { - throw new VizException( "i/o error copying default attr set file."); - } - } - } - seldRscDefn = newRscDefn; - - ResourceName newSeldRscName = new ResourceName(); - newSeldRscName.setRscCategory( seldRscDefn.getResourceCategory() ); - newSeldRscName.setRscType( seldRscDefn.getResourceDefnName() ); - - mngrControl.updateResourceSelections( newSeldRscName ); - - } catch (VizException e) { - MessageDialog errDlg = new MessageDialog(getShell(), - "New Resource Type", null, - "Error Creating new Type " +rscTypeName + "\n\n"+ - e.getMessage(), - MessageDialog.ERROR, new String[]{"OK"}, 0); - errDlg.open(); - return; - } - } - - // The name of the resource type hasn't changed - // - protected void saveResourceDefinition( ) { - - ResourceDefinition saveRD = new ResourceDefinition( seldRscDefn ); - - setSelectedRscDefnFromGUI( seldRscDefn ); - - Boolean filtersChanged = false; - - String newFiltsStr = filterLabelsTxt.getText().trim(); - StringListAdapter listAdpr = new StringListAdapter(); - - try { - String curFiltsStr = listAdpr.marshal( - rscDefnMngr.getResourceDefnFilter( seldRscDefn.getResourceDefnName() ).getFilters() ).trim(); - - if( !curFiltsStr.equals( newFiltsStr ) ) { - filtersChanged = true; - -// save the new filters to the map and the File - ResourceDefinitionFilter rdFilt = - rscDefnMngr.getResourceDefnFilter( seldRscDefn.getResourceDefnName() ); - rdFilt.setFilters( listAdpr.unmarshal( newFiltsStr ) ); - rscDefnMngr.setResourceDefnFilters( rdFilt ); - - rscDefnMngr.saveResourceDefnFiltersFile(); - } - } catch (Exception e) { - MessageDialog errDlg = new MessageDialog( getShell(), - "Save Resource Filters", null, - "Error Saving Filters for Rsc Defn:\n\n"+ - e.getMessage(), MessageDialog.ERROR, new String[]{"OK"}, 0); - errDlg.open(); - } - - // check to see if the user has made any changes to the RD and if - // not we don't need to save it. - if( saveRD.equals( seldRscDefn ) ) { - if( filtersChanged ) { - MessageDialog msgDlg = new MessageDialog( getShell(), - "Saved", null, - "The Filters for " + seldRscDefn.getResourceDefnName() + " have been saved to :.\n"+ - NcPathConstants.RESOURCE_FILTERS + ". No changes were made to the Rsc Defn File.", - MessageDialog.INFORMATION, new String[]{"OK"}, 0); - msgDlg.open(); - return; - } - } - - String rscTypeName = rscTypeTxt.getText().trim(); - String rscTypeGen = ""; - - int indx = rscTypeName.indexOf(":${"); - - // if there is a type generator then parse the rscType name and the name of the appending generator parameter - if( indx != -1 ) { - rscTypeGen = rscTypeName.substring(indx+2); - rscTypeName = rscTypeName.substring(0,indx); - indx = rscTypeGen.indexOf("}"); - if( indx != -1 ) { - rscTypeGen = rscTypeGen.substring(0,indx); - } - } - - LocalizationFile lFile = seldRscDefn.getLocalizationFile(); - - if( lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - MessageDialog confirmDlg = new MessageDialog( getShell(), - "Confirm", null, - "This will overwrite the current User-Level Resource Type\n"+ - "Are you sure you want to do this?", - MessageDialog.CONFIRM, new String[]{"Yes", "No"}, 0); - confirmDlg.open(); - - if( confirmDlg.getReturnCode() == MessageDialog.CANCEL ) { - return; - } - } -// else { // create a new user-level lFile -// LocalizationContext newContext = NcPathManager.getInstance().getContext( -// lFile.getContext().getLocalizationType(), -// LocalizationLevel.USER ); -// lFile = NcPathManager.getInstance().getLocalizationFile( newContext, -// lFile.getName() ); -// seldRscDefn.setLocalizationFile(lFile); -// } - - try { - rscDefnMngr.saveResourceDefn( seldRscDefn ); - - if( filtersChanged ) { - MessageDialog msgDlg = new MessageDialog( getShell(), - "Saved", null, - "The Resource " + rscTypeName + " has been saved to a USER-level file.\n"+ - "and the Filters in the "+NcPathConstants.RESOURCE_FILTERS+" file have been updated.", - MessageDialog.INFORMATION, new String[]{"OK"}, 0); - msgDlg.open(); - } - else { - MessageDialog msgDlg = new MessageDialog( getShell(), - "Saved", null, - "The Resource " + rscTypeName + " has been saved.\n", - MessageDialog.INFORMATION, new String[]{"OK"}, 0); - msgDlg.open(); - } - - } catch (VizException e) { - MessageDialog confirmDlg = new MessageDialog( getShell(), - "Save Resource Type", null, - "Error Writing new Resource Definitions Table\n\n"+ - e.getMessage(), - MessageDialog.ERROR, new String[]{"OK"}, 0); - confirmDlg.open(); - } - - mngrControl.updateResourceSelections( null ); - - return; - } - - // update the seldRscDefn with the GUI selections - // - private void setSelectedRscDefnFromGUI( ResourceDefinition rscDefn ) { - - rscDefn.setDfltFrameCount( dfltNumFramesSpnr.getSelection() ); - - for( TimeMatchMethod tmm : TimeMatchMethod.values() ) { - if( timeMatchMethodCombo.getText().equals( tmm.toString() ) ) { - rscDefn.setTimeMatchMethod( tmm ); - break; - } - } - - if( frameSpanCombo.getText().equals("N/A") ) { - rscDefn.setFrameSpan( 0 ); - } - else { - for( int i=0; i availRscImplementations = ResourceExtPointMngr + .getInstance().getAvailResources(); + + rscTypeTxt.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + + String newTextStr = rscTypeTxt.getText().trim(); + + int indx = newTextStr.indexOf("${"); + + if (indx != -1) { + newTextStr = newTextStr.substring(0, indx - 1); + } + + if (newTextStr.isEmpty()) { + saveTypeBtn.setEnabled(false); + newTypeBtn.setEnabled(false); + } else { + saveTypeBtn.setEnabled(true); + + // if the name has been changed, the 'save' button acts as a + // 'Rename' or Save As + // + // disable the New button if the name hasn't been changed. + // + if (seldRscDefn.getResourceDefnName().equals(newTextStr)) { + saveTypeBtn.setText("Save"); + + newTypeBtn.setEnabled(false); + } else { + saveTypeBtn.setText("Save As"); + newTypeBtn.setEnabled(true); + + // disable the Save button if the new name already + // exists + String rscType = newTextStr; + + // ResourceDefinition.getResourceType( + // rscTypeTxt.getText().trim() ); + + if (rscDefnMngr.findResourceDefinition(rscType)) { + saveTypeBtn.setEnabled(false); + } + } + } + } + }); + + useFrameIntrvlBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + // frameIntervalCombo.setEnabled( + // useTimeIntrvlBtn.getSelection() ); + // timeIntervalCombo.setVisible( useTimeIntrvlBtn.getSelection() + // ); + // minsLbl1.setVisible( useTimeIntrvlBtn.getSelection() ); + } + }); + + binDataBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + binStartIntrvlSpnr.setVisible(binDataBtn.getSelection()); + binEndIntrvlSpnr.setVisible(binDataBtn.getSelection()); + startLbl.setVisible(binDataBtn.getSelection()); + endLbl.setVisible(binDataBtn.getSelection()); + minsLbl2.setVisible(binDataBtn.getSelection()); + minsLbl3.setVisible(binDataBtn.getSelection()); + } + }); + + editParamsTxt.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + } + }); + + // subTypeGenTxt.addVerifyListener( new VerifyListener() { + // @Override + // public void verifyText(VerifyEvent event) { + // String text = ((Text) event.widget).getText(); + // String newText = event.text; + // + // if( !text.startsWith("${") || + // !text.endsWith("}" ) ) { + // event.doit = false; + // return; + // } + // } + // }); + + saveTypeBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + saveResourceDefinition(); + } + }); + + newTypeBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + createResourceDefinition(); + } + }); + + cancelBtn.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent ev) { + mngrControl.editActionCanceled(); + } + }); + } + + @Override + public ResourceName getSelectedResourceName() { + return seldRscName; + } + + // TODO : not implemented + @Override + public boolean isModified() { + return false; + } + + @Override + public void activate() { + setVisible(true); + if (getParent() instanceof Group) { + ((Group) getParent()).setText(getTitle()); + } + } + + public void copySelectedResource(ResourceName rscName) { + setSelectedResource(rscName); + newTypeBtn.setVisible(true); + saveTypeBtn.setVisible(false); + rscTypeTxt.setEditable(true); + rscTypeTxt.setBackground(editParamsTxt.getBackground()); // set white to + // indicate + // editable + + rscTypeTxt.setText("CopyOf" + rscTypeTxt.getText()); + rscTypeTxt.setSelection(0, rscTypeTxt.getText().length()); + rscTypeTxt.setFocus(); + } + + public void editSelectedResource(ResourceName rscName) { + setSelectedResource(rscName); + newTypeBtn.setVisible(false); + saveTypeBtn.setVisible(true); + + rscTypeTxt.setEditable(false); + rscTypeTxt.setBackground(getParent().getBackground()); + } + + public void setSelectedResource(ResourceName rscName) { + + seldRscName = rscName; + + if (seldRscName.getRscType().isEmpty()) { + rscTypeTxt.setText(""); + saveTypeBtn.setEnabled(false); + } else { + + if (seldRscName.getRscCategory().toString().equals("TIMESERIES")) { + dfltNumFramesSpnr.setEnabled(false); + dfltNumFramesLbl.setEnabled(false); + } else { + dfltNumFramesSpnr.setEnabled(true); + dfltNumFramesLbl.setEnabled(true); + } + + saveTypeBtn.setEnabled(false); + + seldRscDefn = new ResourceDefinition( + rscDefnMngr.getResourceDefinition(seldRscName)); + + if (seldRscDefn == null) { // ???? + System.out.println("Unable to get Resource Defn for:" + + seldRscName); + return; + } + + String rscTypeGen = seldRscDefn.getRscTypeGenerator(); + + if (rscTypeGen != null && !rscTypeGen.isEmpty()) { + rscTypeTxt.setText(seldRscName.getRscType() + ":${" + + rscTypeGen + "}"); + } else { + rscTypeTxt.setText(seldRscName.getRscType()); + } + + // set the frame count + int numFrames = seldRscDefn.getDfltFrameCount(); + dfltNumFramesSpnr.setSelection(numFrames); + + // if we let any resource select Manual timeline then we need + // another way to + // specify 'Event-type' resources .... + TimelineGenMethod timelineMthd = seldRscDefn.getTimelineGenMethod(); + + useDataTimesBtn.setEnabled(true); + useFrameIntrvlBtn.setEnabled(true); + useFcstDataTimesBtn.setEnabled(true); + useManualTimelineBtn.setEnabled(true); + useFcstFrameIntrvlBtn.setEnabled(false); + + useDataTimesBtn.setSelection(false); + useFcstDataTimesBtn.setSelection(false); + useFrameIntrvlBtn.setSelection(false); + useManualTimelineBtn.setSelection(false); + useFcstFrameIntrvlBtn.setSelection(false); + + if (timelineMthd == TimelineGenMethod.USE_DATA_TIMES) { + useDataTimesBtn.setSelection(true); + } else if (timelineMthd == TimelineGenMethod.USE_CYCLE_TIME_FCST_HOURS) { + useFcstDataTimesBtn.setSelection(true); + } else if (timelineMthd == TimelineGenMethod.USE_FRAME_INTERVAL) { + useFrameIntrvlBtn.setSelection(true); + } else if (timelineMthd == TimelineGenMethod.USE_MANUAL_TIMELINE) { + useManualTimelineBtn.setSelection(true); + } + // just for TAF for now. So don't let the user change it and just + // show + else if (timelineMthd == TimelineGenMethod.USE_FCST_FRAME_INTERVAL_FROM_REF_TIME) { + useFcstFrameIntrvlBtn.setEnabled(true); + useFcstFrameIntrvlBtn.setSelection(true); + + useFrameIntrvlBtn.setEnabled(false); + useDataTimesBtn.setEnabled(false); + useFcstDataTimesBtn.setEnabled(false); + useManualTimelineBtn.setEnabled(false); + } + + // if this is an event type resource; modify the + // timeMatchMthd, frameInterval and timelineGeneration selections + timeMatchMethodCombo.removeAll(); + frameSpanCombo.removeAll(); + + if (seldRscDefn.getTimeMatchMethod() == TimeMatchMethod.EVENT) { + + useDataTimesBtn.setSelection(false); // sanity check since + useFrameIntrvlBtn.setSelection(false); // all event resources + // should + useManualTimelineBtn.setSelection(true); // be set to MANUAL + // anyway + + useDataTimesBtn.setEnabled(false); + useFcstDataTimesBtn.setEnabled(false); + useFrameIntrvlBtn.setEnabled(false); + + // For event resources, only EXACT is meaningful + timeMatchMethodCombo.add(TimeMatchMethod.EVENT.toString()); + timeMatchMethodCombo.select(0); + + // for Event resources the frameSpan is the default Frame + // Interval + frameIntLbl.setText("Dflt Frame Interval"); + // frameSpanCombo.add( "N/A" ); + // frameSpanCombo.select(0); + frameSpanCombo.setItems(availFrameSpanStrings); + frameSpanCombo + .setToolTipText("For this Event-Type resource the Default Frame Interval is \n" + + "used to set the initial Frame Interval for a Manual timeline."); + + int frameSpan = seldRscDefn.getFrameSpan(); + frameSpanCombo.deselectAll(); + + for (int i = 0; i < availFrameSpanMins.length; i++) { + if (availFrameSpanMins[i] == frameSpan) { + frameSpanCombo.select(i); + break; + } + } + + binDataBtn.setEnabled(false); + } else { + for (TimeMatchMethod tmm : TimeMatchMethod.values()) { + timeMatchMethodCombo.add(tmm.toString()); + } + + TimeMatchMethod timeMatchMthd = seldRscDefn + .getTimeMatchMethod(); + int comboIndx = 0; + + for (comboIndx = 0; comboIndx < timeMatchMethodCombo + .getItemCount(); comboIndx++) { + if (timeMatchMthd.toString().equals( + timeMatchMethodCombo.getItem(comboIndx))) { + timeMatchMethodCombo.select(comboIndx); + break; + } + } + if (comboIndx < timeMatchMethodCombo.getItemCount()) { + } + + frameIntLbl.setText("Frame Span"); + frameSpanCombo.setItems(availFrameSpanStrings); + frameSpanCombo + .setToolTipText("The Frame Span for a resource is the maximum range of times for " + + "data displayed in the frame."); + + int frameSpan = seldRscDefn.getFrameSpan(); + frameSpanCombo.deselectAll(); + + for (int i = 0; i < availFrameSpanMins.length; i++) { + if (availFrameSpanMins[i] == frameSpan) { + frameSpanCombo.select(i); + break; + } + } + + binDataBtn.setEnabled(true); + } + + int timeRangeHrs = seldRscDefn.getDfltTimeRange(); // in hours + int timeRangeDays = timeRangeHrs / 24; + timeRangeHrs %= 24; + + dfltTimeRangeDaysSpnr.setSelection(timeRangeDays); + dfltTimeRangeHrsSpnr.setSelection(timeRangeHrs); + + if (seldRscDefn.getResourceParametersAsString().isEmpty()) { + editParamsTxt.setVisible(false); + editParamsLbl.setVisible(false); + } else { + editParamsTxt.setVisible(true); + editParamsTxt.setText(seldRscDefn + .getResourceParametersAsString()); + editParamsLbl.setVisible(true); + } + + ResourceDefinitionFilter rdFilt = rscDefnMngr + .getResourceDefnFilter(seldRscDefn.getResourceDefnName()); + StringListAdapter sla = new StringListAdapter(); + + String filtLabelsStr = ""; + try { + filtLabelsStr = sla.marshal(rdFilt.getFilters()); + } catch (Exception e) { + } + + filterLabelsTxt.setText(filtLabelsStr); + filterLabelsLbl.setText("Filterable Labels (" + + rdFilt.getLocLevel().toString() + " Level)"); + + editParamsLbl.setText("Edit Parameters for " + + seldRscDefn.getRscImplementation()); + + rscImplTxt.setText(seldRscDefn.getRscImplementation()); + + // if( seldRscDefn.getResourceCategory().equals( + // ResourceName.RadarRscCategory ) || + // seldRscDefn.getResourceCategory().equals( + // ResourceName.SatelliteRscCategory ) ) { + if (!seldRscDefn.getSubTypeGenerator().isEmpty()) { + // subTypeGenTxt.setEnabled( true ); + subTypeGenTxt.setVisible(true); + subTypeGenLbl.setVisible(true); + subTypeGenTxt.setText(seldRscDefn.getSubTypeGenerator()); + } else { + // subTypeGenTxt.setEnabled( false ); + subTypeGenTxt.setVisible(false); + subTypeGenLbl.setVisible(false); + subTypeGenTxt.setText(""); + } + + // BinOffset binOffset = seldRscDefn.getBinOffset(); + + // binDataBtn.setSelection( binOffset != null ); + binStartIntrvlSpnr.setVisible(false);// binDataBtn.getSelection() ); + binEndIntrvlSpnr.setVisible(false);// binDataBtn.getSelection() ); + startLbl.setVisible(false);// binDataBtn.getSelection() ); + endLbl.setVisible(false);// binDataBtn.getSelection() ); + + minsLbl2.setVisible(false);// binDataBtn.getSelection() ); + minsLbl3.setVisible(false);// binDataBtn.getSelection() ); + } + } + + @Override + public void deactivate() { + setVisible(false); + } + + @Override + public String getTitle() { + return "Edit Resource Type"; + } + + protected void createResourceDefinition() { + ResourceDefinition newRscDefn = new ResourceDefinition(seldRscDefn); + + String rscTypeName = rscTypeTxt.getText().trim(); + String rscTypeGen = ""; + + int indx = rscTypeName.indexOf(":${"); + + // if there is a type generator then parse the rscType name and the name + // of the appending generator parameter + if (indx != -1) { + rscTypeGen = rscTypeName.substring(indx + 2); + rscTypeName = rscTypeName.substring(0, indx); + indx = rscTypeGen.indexOf("}"); + if (indx != -1) { + rscTypeGen = rscTypeGen.substring(0, indx); + } + } + + if (rscDefnMngr.getResourceDefinition(rscTypeName) != null) { + + MessageDialog confirmDlg = new MessageDialog(getShell(), + "Resource Exist", null, "The Resource Type " + rscTypeName + + " already exists.\n\n" + + "Enter a different name.", + MessageDialog.INFORMATION, new String[] { "OK" }, 0); + confirmDlg.open(); + return; + } + + newRscDefn.setResourceDefnName(rscTypeName); + + setSelectedRscDefnFromGUI(newRscDefn); + + // get the filters and create an entry in the filters map and save the + // file + // + StringListAdapter strListAdptr = new StringListAdapter(); + + List filtersList = null; + try { + filtersList = strListAdptr.unmarshal(filterLabelsTxt.getText() + .trim()); + } catch (Exception e1) { + MessageDialog warnDlg = new MessageDialog( + getShell(), + "Resource", + null, + "Unable to parse the filters string.\n" + + "This should be a list of comma separated strings.", + MessageDialog.WARNING, new String[] { "OK" }, 0); + warnDlg.open(); + } + + ResourceDefinitionFilter rdFilt = rscDefnMngr + .getResourceDefnFilter(seldRscDefn.getResourceDefnName()); + + rdFilt = new ResourceDefinitionFilter(newRscDefn.getResourceDefnName(), + rdFilt.getIsEnabled(), filtersList, LocalizationLevel.USER); + + rscDefnMngr.setResourceDefnFilters(rdFilt); + + try { + rscDefnMngr.saveResourceDefnFiltersFile(); + } catch (VizException e1) { + MessageDialog errDlg = new MessageDialog(getShell(), "Resource", + null, "Error saving a new Resource Filters File:\n" + + e1.getMessage(), MessageDialog.ERROR, + new String[] { "OK" }, 0); + errDlg.open(); + } + + // if attrSetGroups apply then we will just create 1 standard + // attrSetGroup with nothing in + // it. The user will need to edit this later. + // TODO : allow the user to copy all (or some?) of the + // attributeSetGroups from the + // original rscDefn. + + String newLocFilename = seldRscDefn.getLocalizationFile().getName(); + + // peal off the filename and last directory of the same name + // and replace with a path and filename based on the new name + newLocFilename = newLocFilename.substring(0, + newLocFilename.lastIndexOf(File.separator)); + newLocFilename = newLocFilename.substring(0, + newLocFilename.lastIndexOf(File.separator) + 1) + + rscTypeName + File.separator + rscTypeName + ".xml"; + + newRscDefn.setLocalizationFile(null); + newRscDefn.setLocalizationName(newLocFilename); + + // seldRscDefn.setResourceDefnName( rscTypeName ); + // String origRscType = seldRscDefn.getResourceDefnName(); + + try { + rscDefnMngr.saveResourceDefn(newRscDefn); + + // create a new attrSetGroup + if (newRscDefn.applyAttrSetGroups()) { + if (!newRscDefn.isPgenResource()) { + AttrSetGroup asg = new AttrSetGroup(); + asg.setResource(newRscDefn.getResourceDefnName()); + asg.setAttrSetGroupName("standard"); + + rscDefnMngr.saveAttrSetGroup(asg); + } + } + // Copy all of the attr sets + else { + List availAttrSets = rscDefnMngr + .getAttrSetsForResource(seldRscName, false); + + for (AttributeSet attrSet : availAttrSets) { + try { + FileReader fr = new FileReader(attrSet.getFile() + .getFile()); + char[] attrsSetStr = new char[(int) attrSet.getFile() + .getFile().length()]; + fr.read(attrsSetStr); + fr.close(); + + rscDefnMngr.saveAttrSet(newRscDefn, attrSet.getName(), + new String(attrsSetStr)); + + } catch (FileNotFoundException fnf) { + throw new VizException( + "file not found for default attr set."); + } catch (IOException ioe) { + throw new VizException( + "i/o error copying default attr set file."); + } + } + } + seldRscDefn = newRscDefn; + + ResourceName newSeldRscName = new ResourceName(); + newSeldRscName.setRscCategory(seldRscDefn.getResourceCategory()); + newSeldRscName.setRscType(seldRscDefn.getResourceDefnName()); + + mngrControl.updateResourceSelections(newSeldRscName); + + } catch (VizException e) { + MessageDialog errDlg = new MessageDialog(getShell(), + "New Resource Type", null, "Error Creating new Type " + + rscTypeName + "\n\n" + e.getMessage(), + MessageDialog.ERROR, new String[] { "OK" }, 0); + errDlg.open(); + return; + } + } + + // The name of the resource type hasn't changed + // + protected void saveResourceDefinition() { + + ResourceDefinition saveRD = new ResourceDefinition(seldRscDefn); + + setSelectedRscDefnFromGUI(seldRscDefn); + + Boolean filtersChanged = false; + + String newFiltsStr = filterLabelsTxt.getText().trim(); + StringListAdapter listAdpr = new StringListAdapter(); + + try { + String curFiltsStr = listAdpr.marshal( + rscDefnMngr.getResourceDefnFilter( + seldRscDefn.getResourceDefnName()).getFilters()) + .trim(); + + if (!curFiltsStr.equals(newFiltsStr)) { + filtersChanged = true; + + // save the new filters to the map and the File + ResourceDefinitionFilter rdFilt = rscDefnMngr + .getResourceDefnFilter(seldRscDefn + .getResourceDefnName()); + rdFilt.setFilters(listAdpr.unmarshal(newFiltsStr)); + rscDefnMngr.setResourceDefnFilters(rdFilt); + + rscDefnMngr.saveResourceDefnFiltersFile(); + } + } catch (Exception e) { + MessageDialog errDlg = new MessageDialog(getShell(), + "Save Resource Filters", null, + "Error Saving Filters for Rsc Defn:\n\n" + e.getMessage(), + MessageDialog.ERROR, new String[] { "OK" }, 0); + errDlg.open(); + } + + // check to see if the user has made any changes to the RD and if + // not we don't need to save it. + if (saveRD.equals(seldRscDefn)) { + if (filtersChanged) { + MessageDialog msgDlg = new MessageDialog( + getShell(), + "Saved", + null, + "The Filters for " + + seldRscDefn.getResourceDefnName() + + " have been saved to :.\n" + + NcPathConstants.RESOURCE_FILTERS + + ". No changes were made to the Rsc Defn File.", + MessageDialog.INFORMATION, new String[] { "OK" }, 0); + msgDlg.open(); + return; + } + } + + String rscTypeName = rscTypeTxt.getText().trim(); + String rscTypeGen = ""; + + int indx = rscTypeName.indexOf(":${"); + + // if there is a type generator then parse the rscType name and the name + // of the appending generator parameter + if (indx != -1) { + rscTypeGen = rscTypeName.substring(indx + 2); + rscTypeName = rscTypeName.substring(0, indx); + indx = rscTypeGen.indexOf("}"); + if (indx != -1) { + rscTypeGen = rscTypeGen.substring(0, indx); + } + } + + LocalizationFile lFile = seldRscDefn.getLocalizationFile(); + + if (lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + MessageDialog confirmDlg = new MessageDialog(getShell(), "Confirm", + null, + "This will overwrite the current User-Level Resource Type\n" + + "Are you sure you want to do this?", + MessageDialog.CONFIRM, new String[] { "Yes", "No" }, 0); + confirmDlg.open(); + + if (confirmDlg.getReturnCode() == MessageDialog.CANCEL) { + return; + } + } + // else { // create a new user-level lFile + // LocalizationContext newContext = + // NcPathManager.getInstance().getContext( + // lFile.getContext().getLocalizationType(), + // LocalizationLevel.USER ); + // lFile = NcPathManager.getInstance().getLocalizationFile( newContext, + // lFile.getName() ); + // seldRscDefn.setLocalizationFile(lFile); + // } + + try { + rscDefnMngr.saveResourceDefn(seldRscDefn); + + if (filtersChanged) { + MessageDialog msgDlg = new MessageDialog(getShell(), "Saved", + null, "The Resource " + rscTypeName + + " has been saved to a USER-level file.\n" + + "and the Filters in the " + + NcPathConstants.RESOURCE_FILTERS + + " file have been updated.", + MessageDialog.INFORMATION, new String[] { "OK" }, 0); + msgDlg.open(); + } else { + MessageDialog msgDlg = new MessageDialog(getShell(), "Saved", + null, "The Resource " + rscTypeName + + " has been saved.\n", + MessageDialog.INFORMATION, new String[] { "OK" }, 0); + msgDlg.open(); + } + + } catch (VizException e) { + MessageDialog confirmDlg = new MessageDialog(getShell(), + "Save Resource Type", null, + "Error Writing new Resource Definitions Table\n\n" + + e.getMessage(), MessageDialog.ERROR, + new String[] { "OK" }, 0); + confirmDlg.open(); + } + + mngrControl.updateResourceSelections(null); + + return; + } + + // update the seldRscDefn with the GUI selections + // + private void setSelectedRscDefnFromGUI(ResourceDefinition rscDefn) { + + rscDefn.setDfltFrameCount(dfltNumFramesSpnr.getSelection()); + + for (TimeMatchMethod tmm : TimeMatchMethod.values()) { + if (timeMatchMethodCombo.getText().equals(tmm.toString())) { + rscDefn.setTimeMatchMethod(tmm); + break; + } + } + + if (frameSpanCombo.getText().equals("N/A")) { + rscDefn.setFrameSpan(0); + } else { + for (int i = 0; i < availFrameSpanStrings.length; i++) { + if (availFrameSpanStrings[i].equals(frameSpanCombo.getText())) { + rscDefn.setFrameSpan(availFrameSpanMins[i]); + break; + } + } + } + + if (useFrameIntrvlBtn.getSelection()) { + rscDefn.setTimelineGenMethod(TimelineGenMethod.USE_FRAME_INTERVAL); + } else if (useFcstDataTimesBtn.getSelection()) { + rscDefn.setTimelineGenMethod(TimelineGenMethod.USE_CYCLE_TIME_FCST_HOURS); + } else if (useDataTimesBtn.getSelection()) { + rscDefn.setTimelineGenMethod(TimelineGenMethod.USE_DATA_TIMES); + } else if (useManualTimelineBtn.getSelection()) { + rscDefn.setTimelineGenMethod(TimelineGenMethod.USE_MANUAL_TIMELINE); + } else if (useFcstFrameIntrvlBtn.getSelection()) { + rscDefn.setTimelineGenMethod(TimelineGenMethod.USE_FCST_FRAME_INTERVAL_FROM_REF_TIME); + } + + int timeRangeHrs = dfltTimeRangeDaysSpnr.getSelection() * 24 + + dfltTimeRangeHrsSpnr.getSelection(); + rscDefn.setDfltTimeRange(timeRangeHrs); + + // The GUI is in minutes and binOffset is in seconds + // if( binDataBtn.getSelection() ) { + // rscDefn.setBinOffset( + // new BinOffset( binEndIntrvlSpnr.getSelection()*60, + // binStartIntrvlSpnr.getSelection()*60 ) ); + // } + // else { + // rscDefn.setBinOffset( null ); + // } + + if (editParamsTxt.isVisible()) { + if (!rscDefn.getResourceParametersAsString().equals( + editParamsTxt.getText())) { + rscDefn.setResourceParamsModified(true); + + rscDefn.setResourceParametersFromString(editParamsTxt.getText()); + } + } + + // don't save the ${ + if (!rscDefn.applyAttrSetGroups()) { + String subTypeGenStr = subTypeGenTxt.getText(); + + rscDefn.setSubTypeGenerator(subTypeGenStr); + } + } + + private String subTypeGenToolTipText = "This is the name of a DB column used to generate " + + "the Sub-Types for this resource type."; + + private String rscImplToolTipText = "This is the name of the NCP Resource implemenation for this " + + "resource type. The implementation specifies the java class that displays the data and defines " + + "what parameters are expected by the java code"; } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF index 1d5205be98..a40d04fd44 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.resources/META-INF/MANIFEST.MF @@ -74,9 +74,12 @@ Export-Package: gov.noaa.nws.ncep.viz.resources; Import-Package: com.raytheon.uf.common.message.response, com.raytheon.uf.common.pointdata, com.raytheon.uf.viz.core.maps, + com.raytheon.uf.viz.xy.graph, + com.raytheon.uf.viz.xy.timeseries.display, com.raytheon.viz.alerts.observers, com.raytheon.viz.core.gl, com.raytheon.viz.core.graphing, + gov.noaa.nws.ncep.common.dataplugin.geomag, gov.noaa.nws.ncep.common.dataplugin.mcidas, gov.noaa.nws.ncep.common.dataplugin.ntrans, gov.noaa.nws.ncep.common.dataplugin.pgen, @@ -84,3 +87,4 @@ Import-Package: com.raytheon.uf.common.message.response, gov.noaa.nws.ncep.edex.plugin.mosaic.common, gov.noaa.nws.ncep.gempak.parameters.colorbar, gov.noaa.nws.ncep.viz.gempak.grid.inv + diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsRequestableResourceData.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsRequestableResourceData.java index 79bf6935c6..8103254c13 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsRequestableResourceData.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsRequestableResourceData.java @@ -83,7 +83,7 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties; * 04/10/2013 #958 qzhou Added autoupdate for solar in isAutoUpdateable * 07/15/2013 #1011 ghull add MATCH_ALL_DATA timeMatchMethod for PgenResource * 06/16/2014 TTR1026 jwu sort data time for local radar in getAvailableDataTimes() - * + * 05/15/2014 #1131 qzhou Added GraphRscCategory. Added dfltGraphRange * * * * @@ -143,6 +143,12 @@ public abstract class AbstractNatlCntrsRequestableResourceData extends @XmlElement protected int dfltNumFrames; + @XmlElement + protected int dfltGraphRange; + + @XmlElement + protected int dfltHourSnap; + @XmlElement protected int dfltTimeRange; // in hours @@ -186,6 +192,8 @@ public abstract class AbstractNatlCntrsRequestableResourceData extends timeMatchMethod = TimeMatchMethod.CLOSEST_BEFORE_OR_AFTER; timelineGenMethod = TimelineGenMethod.USE_DATA_TIMES; frameSpan = 60; + dfltGraphRange = 12; // ? quan + dfltHourSnap = 3; legendColor = new RGB(255, 255, 255); rscExtPointMngr = ResourceExtPointMngr.getInstance(); } @@ -206,9 +214,11 @@ public abstract class AbstractNatlCntrsRequestableResourceData extends // public boolean isAutoUpdateable() { ResourceCategory rscCat = getResourceName().getRscCategory(); + if (rscCat != null && rscCat == ResourceCategory.SatelliteRscCategory || rscCat == ResourceCategory.RadarRscCategory - || rscCat == ResourceCategory.SpaceRscCategory) { + || rscCat == ResourceCategory.SpaceRscCategory + || rscCat == ResourceCategory.GraphRscCategory) { return true; } return false; @@ -271,6 +281,22 @@ public abstract class AbstractNatlCntrsRequestableResourceData extends this.dfltNumFrames = dfltNumFrames; } + public int getDfltGraphRange() { + return dfltGraphRange; + } + + public void setDfltGraphRange(int dfltGraphRange) { + this.dfltGraphRange = dfltGraphRange; + } + + public int getDfltHourSnap() { + return dfltHourSnap; + } + + public void setDfltHourSnap(int dfltHourSnap) { + this.dfltHourSnap = dfltHourSnap; + } + public int getDfltTimeRange() { return dfltTimeRange; } diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResource.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResource.java index 2893449ad5..c2ba84c11c 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResource.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResource.java @@ -13,7 +13,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; -import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentLinkedQueue; @@ -24,19 +23,14 @@ import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IRenderableDisplayChangedListener; -import com.raytheon.uf.viz.core.IRenderableDisplayChangedListener.DisplayChangeType; import com.raytheon.uf.viz.core.catalog.LayerProperty; import com.raytheon.uf.viz.core.catalog.ScriptCreator; import com.raytheon.uf.viz.core.comm.Connector; -import com.raytheon.uf.viz.core.drawables.AbstractDescriptor; import com.raytheon.uf.viz.core.drawables.IDescriptor; -import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; -import com.raytheon.uf.viz.core.drawables.IDescriptor.FrameChangeMode; -import com.raytheon.uf.viz.core.drawables.IDescriptor.FrameChangeOperation; import com.raytheon.uf.viz.core.drawables.IFrameCoordinator; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.PaintProperties; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.map.IMapDescriptor; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; import com.raytheon.uf.viz.core.rsc.LoadProperties; @@ -59,715 +53,799 @@ import com.raytheon.uf.viz.core.rsc.ResourceType; * 20 Mar 2012 #700 B. Hebbard In processNewRscDataList(), when new frame(s) are created by auto update, * set frame to LAST and issueRefresh() to force paint (per legacy; TTR 520). * 06 Feb 2013 #972 G. Hull define on IDescriptor instead of IMapDescriptor - * + * 06/16/2014 #1136 qzhou remove final for paintInternal, since paintFrame does not work for Graph * * * @author ghull * @version 1 */ public abstract class AbstractNatlCntrsResource - extends AbstractVizResource - implements INatlCntrsResource { - - // NOT USED now but may make sense to have a displayChange listener for all resources? - private class displayChangeListener implements IRenderableDisplayChangedListener { + extends + AbstractVizResource + implements INatlCntrsResource { - @Override - public void renderableDisplayChanged(IDisplayPane pane, - IRenderableDisplay newRenderableDisplay, DisplayChangeType type) { - } - } - public static interface IRscDataObject { - abstract DataTime getDataTime(); - } - - // a wrapper for the common case when a PluginDataObject is the resource Data Object. - // - public static class DfltRecordRscDataObj implements IRscDataObject { - private PluginDataObject pdo; + // NOT USED now but may make sense to have a displayChange listener for all + // resources? + private class displayChangeListener implements + IRenderableDisplayChangedListener { - public DfltRecordRscDataObj( PluginDataObject o ) { - pdo = o; - } - - @Override - public DataTime getDataTime() { - return pdo.getDataTime(); - } - - public PluginDataObject getPDO() { - return pdo; - } - } - - // the expected class for the resourceDataObjects - //protected Class rscDataObjectClass; - - //protected static DataTime lastFrameEndTime; - - public abstract class AbstractFrameData { - - protected DataTime frameTime; + @Override + public void renderableDisplayChanged(IDisplayPane pane, + IRenderableDisplay newRenderableDisplay, DisplayChangeType type) { + } + } - // for resources that need to populated the frames only when the frame is - // first displayed. - protected boolean populated; + public static interface IRscDataObject { + abstract DataTime getDataTime(); + } - protected DataTime startTime; // valid times without a forecast hour - protected DataTime endTime; - - protected long startTimeMillis; - protected long endTimeMillis; - - // set the frame start and end time based on: - // - frame time (from dominant resource), - // - the frameInterval for this resource (may be different than the - // frame interval used to generate the timeline) and - // - the timeMatchMethod. - protected AbstractFrameData( DataTime ftime, int frameInterval ) { + // a wrapper for the common case when a PluginDataObject is the resource + // Data Object. + // + public static class DfltRecordRscDataObj implements IRscDataObject { + private PluginDataObject pdo; - // if there is a validPeriod or levels, ignore them and just use the valid time. - this.frameTime = new DataTime( ftime.getRefTime(), ftime.getFcstTime() ); - this.populated = false; - long frameMillis = frameTime.getValidTime().getTimeInMillis(); + public DfltRecordRscDataObj(PluginDataObject o) { + pdo = o; + } - switch( resourceData.getTimeMatchMethod() ) { + @Override + public DataTime getDataTime() { + return pdo.getDataTime(); + } - case EXACT : { - startTime = new DataTime( frameTime.getValidTime() ); - endTime = new DataTime( frameTime.getValidTime() ); - } - // Note : Currently this is implemented the same as Exact. (ie the frame time - // must be between the start/end time of an event.) A more general algorithm - // could be implemented to use the frame span and test whether any part of the - // event overlaps with any part of the frame span. But currently, for Event resources, - // the frame span is taken as the default frame interval for a manual timeline and so - // this would need to be addressed first.) - case EVENT : { - startTime = new DataTime( frameTime.getValidTime() ); - endTime = new DataTime( frameTime.getValidTime() ); - } - case CLOSEST_BEFORE_OR_AFTER : { - startTime = new DataTime( new Date(frameMillis - frameInterval*1000*60/2 ) ); - endTime = new DataTime( new Date(frameMillis + frameInterval*1000*60/2-1000 ) ); - break; - } - case CLOSEST_BEFORE_OR_EQUAL : { - startTime = new DataTime( new Date(frameMillis - frameInterval*1000*60 ) ); - endTime = new DataTime( frameTime.getValidTime() ); - break; - } - case CLOSEST_AFTER_OR_EQUAL : { - startTime = new DataTime( frameTime.getValidTime() ); - endTime = new DataTime( new Date(frameMillis + frameInterval*1000*60-1000 ) ); - break; - } - case BEFORE_OR_EQUAL : { - startTime = new DataTime( new Date(0) ); - endTime = new DataTime( frameTime.getValidTime() ); - break; - } - // This could be implemented by setting the frame span to infinite. - case MATCH_ALL_DATA : { - startTime = new DataTime( new Date(0) ); - endTime = new DataTime( new Date(Long.MAX_VALUE) ); - } - } - - startTimeMillis = startTime.getValidTime().getTimeInMillis(); - endTimeMillis = endTime.getValidTime().getTimeInMillis(); - } - - final public boolean isRscDataObjInFrame( IRscDataObject rscDataObj ) { - DataTime dataTime = rscDataObj.getDataTime(); - return ( dataTime == null ? false : timeMatch( dataTime ) >= 0 ); - } - - // return -1 if the data doesn't match. if the return value is 0 or positive - // then this is the number of seconds from the perfect match. - public long timeMatch( DataTime dataTime ) { - - long dataTimeMillis = dataTime.getValidTime().getTimeInMillis(); - TimeRange dataTimeRange = dataTime.getValidPeriod(); - - switch( resourceData.getTimeMatchMethod() ) { + public PluginDataObject getPDO() { + return pdo; + } + } - case MATCH_ALL_DATA : // everything is a perfect match. (for PGEN Resource) - return 0; - case EXACT : case EVENT : { - long frameTimeMillis = frameTime.getValidTime().getTimeInMillis(); - - if( dataTimeRange.isValid() ) { - if( dataTimeRange.getStart().getTime() <= frameTimeMillis && - frameTimeMillis <= dataTimeRange.getEnd().getTime() ) { - return 0; - } - else { - return -1; - } - } - else { - return (frameTimeMillis == dataTimeMillis ? 0 : -1); - } - } - // mainly (only?) for lightning. Might be able to remove this timeMatchMethod - // if lighting resource is modified? - case BEFORE_OR_EQUAL : { - return ( dataTimeMillis > endTimeMillis ? -1 : - (endTimeMillis-dataTimeMillis)/1000); - } - case CLOSEST_BEFORE_OR_AFTER : - case CLOSEST_BEFORE_OR_EQUAL : - case CLOSEST_AFTER_OR_EQUAL : { - // This should be an invalid case. if this is an event type resource then - // it should be an EXACT time match. Still, for now leave this logic in here. - if( dataTimeRange.isValid() ) { - System.out.println("Timematching a dataTime with a valid interval with a non-EXACT\n "+ - "TimeMatchMethod."); - return -1; -// long dataStartTimeMillis = dataTimeRange.getStart().getTime(); -// long dataEndTimeMillis = dataTimeRange.getEnd().getTime(); -// -// if( dataStartTimeMillis > endTimeMillis || -// dataEndTimeMillis <= startTimeMillis ) { -// return false; -// } -// else { -// return true; -// } - } + // the expected class for the resourceDataObjects + // protected Class rscDataObjectClass; - // return -1 if this is not a match. - // (since the start/end times are based on the timeMatchMethod, - // we can just check that the datatime is not within the start/end) - // - if( startTimeMillis >= dataTimeMillis || - dataTimeMillis > endTimeMillis ) { - return -1; - } - // - else if( resourceData.getTimeMatchMethod() == - TimeMatchMethod.CLOSEST_BEFORE_OR_EQUAL ) { - return (endTimeMillis-dataTimeMillis) / 1000; - } - else if( resourceData.getTimeMatchMethod() == - TimeMatchMethod.CLOSEST_AFTER_OR_EQUAL ) { - return (dataTimeMillis-startTimeMillis) / 1000; - } - else if( resourceData.getTimeMatchMethod() == - TimeMatchMethod.CLOSEST_BEFORE_OR_AFTER ) { - return Math.abs( frameTime.getValidTime().getTime().getTime() - - dataTimeMillis) / 1000 ; - } - } - } - return -1; - } - - // only return true if the data was added to the frame. It is possible for - // some resources for the data to time match but not be added because there - // is already data in the frame that is a better match. - // - public abstract boolean updateFrameData(IRscDataObject rscDataObj); + // protected static DataTime lastFrameEndTime; - public void dispose() { - // override this if need to dispose of anything in the Frame. - } - - public DataTime getFrameTime() { - return frameTime; - } - - public DataTime getFrameStartTime() { - return startTime; - } - - public DataTime getFrameEndTime() { - return endTime; - } + public abstract class AbstractFrameData { - public boolean isPopulated() { - return populated; - } - public void setPopulated(boolean p) { - populated = p; - } - - } + protected DataTime frameTime; - protected boolean initialized = false; + // for resources that need to populated the frames only when the frame + // is + // first displayed. + protected boolean populated; - // Map from a frame time string to a structure containing - // displayable data elements for that frame... - protected TreeMap frameDataMap; + protected DataTime startTime; // valid times without a forecast hour - // This list is populated by the initial query and also by the auto update - // when new data is ingested for this resource. These objects time matched - // to one or more frames. - protected ConcurrentLinkedQueue newRscDataObjsQueue; - - // This list caches objects that are ingested and are newer than the latest frame. - // When a frame is later created due to auto updating, these objects are moved to - // the newRscDataObjsQueue. - protected ArrayList autoUpdateCache; - - // the new frame times that will be created during the next auto update - protected ArrayList newFrameTimesList; - - protected DataTime currFrameTime; + protected DataTime endTime; - private boolean autoUpdateReady=false; - - // if the frameGenMthd is USE_FRAME_INTERVAL then this is the time - // when the next frame will be created if autoupdate is on. - // Note: that more than one frame may be created if the user turns - // autoupdate on long after the next frame time has past. - private DataTime nextFrameTime=null; - - - protected AbstractNatlCntrsResource(T resourceData, LoadProperties props) { - super(resourceData, props); - frameDataMap = new TreeMap(); - newRscDataObjsQueue = new ConcurrentLinkedQueue(); - - autoUpdateCache = new ArrayList(); - newFrameTimesList = new ArrayList(); - currFrameTime = null; + protected long startTimeMillis; - // if requestable add a resourceChanged listener that is called by Raytheon's - // AbstractRequestableResource when update() is called. - if( resourceData instanceof AbstractNatlCntrsRequestableResourceData ) { - resourceData.addChangeListener(new IResourceDataChanged() { - @Override - public void resourceChanged(ChangeType type, Object object) { - - if( object == null ) { - System.out.println( "resourceChanged called with null object for "+ - getResourceData().getResourceName().toString() ); - return; - } - - // TODO : need to make sure that these are the same types of - // objects that are returned by the queryRecords method (or the method - // that the resource uses to populate the frameData). - // - if (type == ChangeType.DATA_UPDATE) { - if( object instanceof Object[] ) { - for( Object obj : (Object[])object ) { - for( IRscDataObject dataObj : processRecord( obj ) ) { - newRscDataObjsQueue.add(dataObj); - } - } - } - else { - for( IRscDataObject dataObj : processRecord( object ) ) { - newRscDataObjsQueue.add(dataObj); - } - } - - // can't call processNewRscDataList here since we are not in the UI thread when - // the AutoUpdater calls us and this will end up updating the status line's - // frame time is a new frame is created. - // - autoUpdateReady = true; - } - } - }); - } - } - - // the timeline (times in the timeMatcher) have changed so we must update the - // frames in the frameDataMap and process any data saved in the autoUpdateCache. - // - public Boolean updateTimeline( ) { - NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); - List newFrameTimes = timeMatcher.getFrameTimes(); + protected long endTimeMillis; - // loop thru all of the new frame times and if the frameDataMap doesn't have an entry for - // this time create a new entry. - for( DataTime frameTime : newFrameTimes ) { - if( !frameDataMap.containsKey( frameTime.getValidTime().getTime().getTime() ) ) { - AbstractFrameData newFrame = this.createNewFrame( frameTime, - resourceData.frameSpan ); - frameDataMap.put( frameTime.getValidTime().getTime().getTime(), newFrame ); - } - } + // set the frame start and end time based on: + // - frame time (from dominant resource), + // - the frameInterval for this resource (may be different than the + // frame interval used to generate the timeline) and + // - the timeMatchMethod. + protected AbstractFrameData(DataTime ftime, int frameInterval) { - // loop thru all of the times in the frameDataMap and if the time is not in the - // new frameTimes then remove the frame from the map. - ArrayList frameTimesInMap = new ArrayList( frameDataMap.keySet() ); - - for( long frameTimeMs : frameTimesInMap ) { - if( !newFrameTimes.contains( new DataTime( new Date( frameTimeMs ) ) ) ) { - frameDataMap.get(frameTimeMs).dispose(); - frameDataMap.remove( frameTimeMs ); - } - } - - // copy all of the cached objects for auto update and process them. - // - newRscDataObjsQueue.addAll( autoUpdateCache ); - autoUpdateCache.clear(); - - return true; - } + // if there is a validPeriod or levels, ignore them and just use the + // valid time. + this.frameTime = new DataTime(ftime.getRefTime(), + ftime.getFcstTime()); + this.populated = false; + long frameMillis = frameTime.getValidTime().getTimeInMillis(); - - // This is the default implementation for the common case where the Resource - // simply wants to process the PluginDataObject itself but some resources may - // want to override this method if a record contains more than one 'data object' and - // these objects are to be time matched. (ex. some sigmet resources have multiple sigmets - // per record and each has a separate valid time.) - // - protected IRscDataObject[] processRecord( Object pdo ) { - if( !(pdo instanceof PluginDataObject) ) { - System.out.println( "Resource Impl "+getClass().getName() + " must override " + - "the processRecord method to process data objects of class: "+ - pdo.getClass().getName() ); - return null; - } - - DfltRecordRscDataObj rscDataObj = new DfltRecordRscDataObj( (PluginDataObject)pdo ); - return new DfltRecordRscDataObj[]{ rscDataObj }; - } - - // This assumes that the given time is in the map - // - public AbstractFrameData getFrame( DataTime dataTime ) { - AbstractFrameData frameData = null; - - if( dataTime != null ) { - frameData = frameDataMap.get( dataTime.getValidTime().getTime().getTime() ); - } - return frameData; - } - - public AbstractFrameData getCurrentFrame( ) { - if( currFrameTime == null ) { - return null; - } - return frameDataMap.get( currFrameTime.getValidTime().getTime().getTime() ); - } + switch (resourceData.getTimeMatchMethod()) { - public DataTime getCurrentFrameTime() { - return currFrameTime; - } - - public ArrayList getFrameTimes() { - ArrayList frmTimes = new ArrayList(); - for( long t : frameDataMap.keySet() ) { - frmTimes.add( new DataTime( new Date(t) ) ); - } - return frmTimes; - } - - @Override - public INatlCntrsDescriptor getDescriptor() { - if( super.getDescriptor() instanceof INatlCntrsDescriptor ) { - return (INatlCntrsDescriptor) super.getDescriptor(); - } - System.out.println("AbstractNatlCntrResource.getDescriptor() returning null????"); - return null; - } - - // this should only be called by resources that are instantiated with an NcMapDescriptor - protected NCMapDescriptor getNcMapDescriptor() { - if( getDescriptor() instanceof NCMapDescriptor ) { - return (NCMapDescriptor)getDescriptor(); - } - System.out.println("GetNcMapDescriptor() returning null????"); - return null; - } - - // - public final void initInternal(IGraphicsTarget grphTarget) throws VizException { - if( !initialized ) { - // create the frameDataMap based on the timeFrames from the timeMatcher. - //ArrayList frameTimes - NCTimeMatcher timeMatcher = (NCTimeMatcher)descriptor.getTimeMatcher(); - List frameTimes = timeMatcher.getFrameTimes(); - - for( DataTime frameTime : frameTimes ) { - if( frameTime != null ) { - AbstractFrameData newFrame = this.createNewFrame( frameTime, - resourceData.frameSpan ); - frameDataMap.put( frameTime.getValidTime().getTime().getTime(), newFrame ); - } - } - - // if using a frameInterval to generate the timeline, predict the - // time for the next frame which will be created if auto updating - if( !frameTimes.isEmpty() && - getResourceData().getTimelineGenMethod() != TimelineGenMethod.USE_DATA_TIMES ) { - nextFrameTime = new DataTime( new Date(frameDataMap.lastKey()), - timeMatcher.getFrameInterval() ); - } - - // This is now done in the NCMapDescriptor when the timeMatcher is set - // -// ((AbstractDescriptor) descriptor).getTimeMatchingMap().put( -// this, frameTimes.toArray( new DataTime[0] ) ); - ((INatlCntrsDescriptor)descriptor).setFrameTimesForResource( - this, frameTimes.toArray( new DataTime[0] ) ); + case EXACT: { + startTime = new DataTime(frameTime.getValidTime()); + endTime = new DataTime(frameTime.getValidTime()); + } + // Note : Currently this is implemented the same as Exact. (ie the + // frame time + // must be between the start/end time of an event.) A more general + // algorithm + // could be implemented to use the frame span and test whether any + // part of the + // event overlaps with any part of the frame span. But currently, + // for Event resources, + // the frame span is taken as the default frame interval for a + // manual timeline and so + // this would need to be addressed first.) + case EVENT: { + startTime = new DataTime(frameTime.getValidTime()); + endTime = new DataTime(frameTime.getValidTime()); + } + case CLOSEST_BEFORE_OR_AFTER: { + startTime = new DataTime(new Date(frameMillis - frameInterval + * 1000 * 60 / 2)); + endTime = new DataTime(new Date(frameMillis + frameInterval + * 1000 * 60 / 2 - 1000)); + break; + } + case CLOSEST_BEFORE_OR_EQUAL: { + startTime = new DataTime(new Date(frameMillis - frameInterval + * 1000 * 60)); + endTime = new DataTime(frameTime.getValidTime()); + break; + } + case CLOSEST_AFTER_OR_EQUAL: { + startTime = new DataTime(frameTime.getValidTime()); + endTime = new DataTime(new Date(frameMillis + frameInterval + * 1000 * 60 - 1000)); + break; + } + case BEFORE_OR_EQUAL: { + startTime = new DataTime(new Date(0)); + endTime = new DataTime(frameTime.getValidTime()); + break; + } + // This could be implemented by setting the frame span to infinite. + case MATCH_ALL_DATA: { + startTime = new DataTime(new Date(0)); + endTime = new DataTime(new Date(Long.MAX_VALUE)); + } + } + + startTimeMillis = startTime.getValidTime().getTimeInMillis(); + endTimeMillis = endTime.getValidTime().getTimeInMillis(); + } + + final public boolean isRscDataObjInFrame(IRscDataObject rscDataObj) { + DataTime dataTime = rscDataObj.getDataTime(); + return (dataTime == null ? false : timeMatch(dataTime) >= 0); + } + + // return -1 if the data doesn't match. if the return value is 0 or + // positive + // then this is the number of seconds from the perfect match. + public long timeMatch(DataTime dataTime) { + + long dataTimeMillis = dataTime.getValidTime().getTimeInMillis(); + TimeRange dataTimeRange = dataTime.getValidPeriod(); + + switch (resourceData.getTimeMatchMethod()) { + + case MATCH_ALL_DATA: // everything is a perfect match. (for PGEN + // Resource) + return 0; + case EXACT: + case EVENT: { + long frameTimeMillis = frameTime.getValidTime() + .getTimeInMillis(); + + if (dataTimeRange.isValid()) { + if (dataTimeRange.getStart().getTime() <= frameTimeMillis + && frameTimeMillis <= dataTimeRange.getEnd() + .getTime()) { + return 0; + } else { + return -1; + } + } else { + return (frameTimeMillis == dataTimeMillis ? 0 : -1); + } + } + // mainly (only?) for lightning. Might be able to remove this + // timeMatchMethod + // if lighting resource is modified? + case BEFORE_OR_EQUAL: { + return (dataTimeMillis > endTimeMillis ? -1 + : (endTimeMillis - dataTimeMillis) / 1000); + } + case CLOSEST_BEFORE_OR_AFTER: + case CLOSEST_BEFORE_OR_EQUAL: + case CLOSEST_AFTER_OR_EQUAL: { + // This should be an invalid case. if this is an event type + // resource then + // it should be an EXACT time match. Still, for now leave this + // logic in here. + if (dataTimeRange.isValid()) { + System.out + .println("Timematching a dataTime with a valid interval with a non-EXACT\n " + + "TimeMatchMethod."); + return -1; + // long dataStartTimeMillis = + // dataTimeRange.getStart().getTime(); + // long dataEndTimeMillis = + // dataTimeRange.getEnd().getTime(); + // + // if( dataStartTimeMillis > endTimeMillis || + // dataEndTimeMillis <= startTimeMillis ) { + // return false; + // } + // else { + // return true; + // } + } + + // return -1 if this is not a match. + // (since the start/end times are based on the timeMatchMethod, + // we can just check that the datatime is not within the + // start/end) + // + if (startTimeMillis >= dataTimeMillis + || dataTimeMillis > endTimeMillis) { + return -1; + } + // + else if (resourceData.getTimeMatchMethod() == TimeMatchMethod.CLOSEST_BEFORE_OR_EQUAL) { + return (endTimeMillis - dataTimeMillis) / 1000; + } else if (resourceData.getTimeMatchMethod() == TimeMatchMethod.CLOSEST_AFTER_OR_EQUAL) { + return (dataTimeMillis - startTimeMillis) / 1000; + } else if (resourceData.getTimeMatchMethod() == TimeMatchMethod.CLOSEST_BEFORE_OR_AFTER) { + return Math.abs(frameTime.getValidTime().getTime() + .getTime() + - dataTimeMillis) / 1000; + } + } + } + return -1; + } + + // only return true if the data was added to the frame. It is possible + // for + // some resources for the data to time match but not be added because + // there + // is already data in the frame that is a better match. + // + public abstract boolean updateFrameData(IRscDataObject rscDataObj); + + public void dispose() { + // override this if need to dispose of anything in the Frame. + } + + public DataTime getFrameTime() { + return frameTime; + } + + public DataTime getFrameStartTime() { + return startTime; + } + + public DataTime getFrameEndTime() { + return endTime; + } + + public boolean isPopulated() { + return populated; + } + + public void setPopulated(boolean p) { + populated = p; + } + + } + + protected boolean initialized = false; + + // Map from a frame time string to a structure containing + // displayable data elements for that frame... + protected TreeMap frameDataMap; + + // This list is populated by the initial query and also by the auto update + // when new data is ingested for this resource. These objects time matched + // to one or more frames. + protected ConcurrentLinkedQueue newRscDataObjsQueue; + + // This list caches objects that are ingested and are newer than the latest + // frame. + // When a frame is later created due to auto updating, these objects are + // moved to + // the newRscDataObjsQueue. + protected ArrayList autoUpdateCache; + + // the new frame times that will be created during the next auto update + protected ArrayList newFrameTimesList; + + protected DataTime currFrameTime; + + private boolean autoUpdateReady = false; + + // if the frameGenMthd is USE_FRAME_INTERVAL then this is the time + // when the next frame will be created if autoupdate is on. + // Note: that more than one frame may be created if the user turns + // autoupdate on long after the next frame time has past. + private DataTime nextFrameTime = null; + + protected AbstractNatlCntrsResource(T resourceData, LoadProperties props) { + super(resourceData, props); + frameDataMap = new TreeMap(); + newRscDataObjsQueue = new ConcurrentLinkedQueue(); + + autoUpdateCache = new ArrayList(); + newFrameTimesList = new ArrayList(); + currFrameTime = null; + + // if requestable add a resourceChanged listener that is called by + // Raytheon's + // AbstractRequestableResource when update() is called. + if (resourceData instanceof AbstractNatlCntrsRequestableResourceData) { + resourceData.addChangeListener(new IResourceDataChanged() { + @Override + public void resourceChanged(ChangeType type, Object object) { + + if (object == null) { + System.out + .println("resourceChanged called with null object for " + + getResourceData().getResourceName() + .toString()); + return; + } + + // TODO : need to make sure that these are the same types of + // objects that are returned by the queryRecords method (or + // the method + // that the resource uses to populate the frameData). + // + if (type == ChangeType.DATA_UPDATE) { + if (object instanceof Object[]) { + for (Object obj : (Object[]) object) { + for (IRscDataObject dataObj : processRecord(obj)) { + newRscDataObjsQueue.add(dataObj); + } + } + } else { + for (IRscDataObject dataObj : processRecord(object)) { + newRscDataObjsQueue.add(dataObj); + } + } + + // can't call processNewRscDataList here since we are + // not in the UI thread when + // the AutoUpdater calls us and this will end up + // updating the status line's + // frame time is a new frame is created. + // + autoUpdateReady = true; + } + } + }); + } + } + + // the timeline (times in the timeMatcher) have changed so we must update + // the + // frames in the frameDataMap and process any data saved in the + // autoUpdateCache. + // + public Boolean updateTimeline() { + NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + List newFrameTimes = timeMatcher.getFrameTimes(); + + // loop thru all of the new frame times and if the frameDataMap doesn't + // have an entry for + // this time create a new entry. + for (DataTime frameTime : newFrameTimes) { + if (!frameDataMap.containsKey(frameTime.getValidTime().getTime() + .getTime())) { + AbstractFrameData newFrame = this.createNewFrame(frameTime, + resourceData.frameSpan); + frameDataMap.put(frameTime.getValidTime().getTime().getTime(), + newFrame); + } + } + + // loop thru all of the times in the frameDataMap and if the time is not + // in the + // new frameTimes then remove the frame from the map. + ArrayList frameTimesInMap = new ArrayList( + frameDataMap.keySet()); + + for (long frameTimeMs : frameTimesInMap) { + if (!newFrameTimes.contains(new DataTime(new Date(frameTimeMs)))) { + frameDataMap.get(frameTimeMs).dispose(); + frameDataMap.remove(frameTimeMs); + } + } + + // copy all of the cached objects for auto update and process them. + // + newRscDataObjsQueue.addAll(autoUpdateCache); + autoUpdateCache.clear(); + + return true; + } + + // This is the default implementation for the common case where the Resource + // simply wants to process the PluginDataObject itself but some resources + // may + // want to override this method if a record contains more than one 'data + // object' and + // these objects are to be time matched. (ex. some sigmet resources have + // multiple sigmets + // per record and each has a separate valid time.) + // + protected IRscDataObject[] processRecord(Object pdo) { + if (!(pdo instanceof PluginDataObject)) { + System.out + .println("Resource Impl " + + getClass().getName() + + " must override " + + "the processRecord method to process data objects of class: " + + pdo.getClass().getName()); + return null; + } + + DfltRecordRscDataObj rscDataObj = new DfltRecordRscDataObj( + (PluginDataObject) pdo); + return new DfltRecordRscDataObj[] { rscDataObj }; + } + + // This assumes that the given time is in the map + // + public AbstractFrameData getFrame(DataTime dataTime) { + AbstractFrameData frameData = null; + + if (dataTime != null) { + frameData = frameDataMap.get(dataTime.getValidTime().getTime() + .getTime()); + } + return frameData; + } + + public AbstractFrameData getCurrentFrame() { + if (currFrameTime == null) { + return null; + } + return frameDataMap.get(currFrameTime.getValidTime().getTime() + .getTime()); + } + + public DataTime getCurrentFrameTime() { + return currFrameTime; + } + + public ArrayList getFrameTimes() { + ArrayList frmTimes = new ArrayList(); + for (long t : frameDataMap.keySet()) { + frmTimes.add(new DataTime(new Date(t))); + } + return frmTimes; + } + + @Override + public INatlCntrsDescriptor getDescriptor() { + if (super.getDescriptor() instanceof INatlCntrsDescriptor) { + return (INatlCntrsDescriptor) super.getDescriptor(); + } + System.out + .println("AbstractNatlCntrResource.getDescriptor() returning null????"); + return null; + } + + // this should only be called by resources that are instantiated with an + // NcMapDescriptor + protected NCMapDescriptor getNcMapDescriptor() { + if (getDescriptor() instanceof NCMapDescriptor) { + return (NCMapDescriptor) getDescriptor(); + } + System.out.println("GetNcMapDescriptor() returning null????"); + return null; + } + + // + public final void initInternal(IGraphicsTarget grphTarget) + throws VizException { + + if (!initialized) { + // create the frameDataMap based on the timeFrames from the + // timeMatcher. + // ArrayList frameTimes + NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor + .getTimeMatcher(); + List frameTimes = timeMatcher.getFrameTimes(); + + for (DataTime frameTime : frameTimes) { + if (frameTime != null) { + AbstractFrameData newFrame = this.createNewFrame(frameTime, + resourceData.frameSpan); + frameDataMap.put(frameTime.getValidTime().getTime() + .getTime(), newFrame); + } + } + + // if using a frameInterval to generate the timeline, predict the + // time for the next frame which will be created if auto updating + if (!frameTimes.isEmpty() + && getResourceData().getTimelineGenMethod() != TimelineGenMethod.USE_DATA_TIMES) { + nextFrameTime = new DataTime(new Date(frameDataMap.lastKey()), + timeMatcher.getFrameInterval()); + } + + // This is now done in the NCMapDescriptor when the timeMatcher is + // set + // + // ((AbstractDescriptor) descriptor).getTimeMatchingMap().put( + // this, frameTimes.toArray( new DataTime[0] ) ); + ((INatlCntrsDescriptor) descriptor).setFrameTimesForResource(this, + frameTimes.toArray(new DataTime[0])); // each resource may decide when and how to populate the frameData. - initResource( grphTarget ); - initialized = true; - } + initResource(grphTarget); + initialized = true; + } } - abstract public void initResource(IGraphicsTarget grphTarget) throws VizException; + abstract public void initResource(IGraphicsTarget grphTarget) + throws VizException; - - // don't let derived classes override paintInternal. Override paintFrame() - public final void paintInternal(IGraphicsTarget target, PaintProperties paintProps) - throws VizException { - - if( !newRscDataObjsQueue.isEmpty() || - (!newFrameTimesList.isEmpty() && - getDescriptor().isAutoUpdate()) ) { - processNewRscDataList(); - } - - if( paintProps == null || paintProps.getDataTime() == null) { - // should we still call the resource's paintFrame in case it needs to do something - // even if there is no time? - return; - } + // don't let derived classes override paintInternal. Override paintFrame() + public void paintInternal(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { - currFrameTime = paintProps.getDataTime(); - AbstractFrameData currFrame = frameDataMap.get( - currFrameTime.getValidTime().getTime().getTime() ); + if (!newRscDataObjsQueue.isEmpty() + || (!newFrameTimesList.isEmpty() && getDescriptor() + .isAutoUpdate())) { + processNewRscDataList(); + } - if( currFrame == null ) { - System.out.println("paint(): Unable to find Frame Data for current Time " - + currFrameTime ); - return; - } + if (paintProps == null || paintProps.getDataTime() == null) { + // should we still call the resource's paintFrame in case it needs + // to do something + // even if there is no time? + return; + } - // let the derived resources do this -// if( !currFrame.isPopulated() ) { -// populateFrame( currFrame ); -// } - - paintFrame(currFrame, target, paintProps); - } + currFrameTime = paintProps.getDataTime(); + AbstractFrameData currFrame = frameDataMap.get(currFrameTime + .getValidTime().getTime().getTime()); - protected abstract void paintFrame(AbstractFrameData frameData, - IGraphicsTarget target, PaintProperties paintProps ) throws VizException; + if (currFrame == null) { + System.out + .println("paint(): Unable to find Frame Data for current Time " + + currFrameTime); + return; + } - - // loop thru newDataObjectsList and update frameDataMap. If a frame for a given - // record time doesn't exist then create a new Frame - // - protected synchronized boolean processNewRscDataList() { // boolean isUpdate ) { - - // allow resources to pre process the data before it is added to the frames - preProcessFrameUpdate(); - - NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + // let the derived resources do this + // if( !currFrame.isPopulated() ) { + // populateFrame( currFrame ); + // } - while( !newRscDataObjsQueue.isEmpty() ) { - IRscDataObject rscDataObj = newRscDataObjsQueue.poll(); - - boolean foundFrame = false; - boolean lastFrame = false; - - // loop through the frames and add this record to all that it time matches to - // - for( AbstractFrameData frameData : frameDataMap.values() ) { - if( frameData != null ) { - if( frameData.isRscDataObjInFrame( rscDataObj ) ) { - if( addRscDataToFrame( frameData, rscDataObj ) ) { - //frameData.setPopulated(true); - foundFrame = true; - } - - if( frameData == frameDataMap.lastEntry().getValue() ) { - lastFrame = true; - } - } - } - } - - // if not in any frames (or if in the last frame) and if updating and if this the data is - // newer than the latest frame then cache the data for auto update. - // NOTE: this will 'drop' (not cache) data from the initial query that doesn't match the - // selected timeline which means that if the user later enables auto-update, this data will - // not be loaded as part of the auto-update. This is by design but could be changed if the - // user wants a different behaviour.) - // NOTE: if the data is in the last frame then it may still potentially match the next frame - // when an update occurs. (WAPITA) (Note2: the auto update code is written to update a frame even - // if it is not the last frame. (ie. data is received out of order for some reason.) but this - // will cause any non-dominant data to not be displayed on these frames because we are only - // checking for the last frame here.) - long dataTimeMs = getDataTimeMs(rscDataObj);//rscDataObj.getDataTime().getValidTime().getTime().getTime(); + paintFrame(currFrame, target, paintProps); + } - if( timeMatcher.isAutoUpdateable()) { + protected abstract void paintFrame(AbstractFrameData frameData, + IGraphicsTarget target, PaintProperties paintProps) + throws VizException; - if( (!foundFrame && autoUpdateReady && - dataTimeMs > frameDataMap.firstKey()) - || lastFrame ) { - // if there is the possibility of auto updating (if the dominant resource - // is a satellite or radar image) then store off the data in the autoUpdateCache - // and then update the timeline if auto update is enabled.. - // - autoUpdateCache.add( rscDataObj ); + // loop thru newDataObjectsList and update frameDataMap. If a frame for a + // given + // record time doesn't exist then create a new Frame + // + protected synchronized boolean processNewRscDataList() { // boolean isUpdate - // if this is the dominantResource, and this data is from a data update alert then - // determine if a new frame is needed. - // - if( isDominantResource() && autoUpdateReady ) { - newFrameTimesList.addAll( - timeMatcher.determineNewFrameTimes( rscDataObj.getDataTime() ) ); - } - } - } - } + // allow resources to pre process the data before it is added to the + // frames + preProcessFrameUpdate(); - // allow resources to post-process the data after it is added to the frames - postProcessFrameUpdate(); + NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); - autoUpdateReady = false; - - // if there is data in the auto update cache and if auto update is now enabled - // and if this is the dominant resource for the timeline then we need to - // update the timeline and process the data in the cache. - // - if( !newFrameTimesList.isEmpty() && - getDescriptor().isAutoUpdate() ) { - - // update the list of times in the timeMatcher. - // this will then trigger the descriptor to update its datatimes and - // notify its resources (including this one) to create and update the frames - timeMatcher.updateTimeline( newFrameTimesList ); - newFrameTimesList.clear(); - // advance to the new last frame (per legacy; could change)... - descriptor.getFrameCoordinator().changeFrame( - IFrameCoordinator.FrameChangeOperation.LAST, - IFrameCoordinator.FrameChangeMode.TIME_ONLY); - // ...and make sure it gets painted - issueRefresh(); - } - - return true; - } + while (!newRscDataObjsQueue.isEmpty()) { + IRscDataObject rscDataObj = newRscDataObjsQueue.poll(); - // break out from updateFrames to allow subclasses to override if needed. - protected boolean addRscDataToFrame( AbstractFrameData frameData, - IRscDataObject rscDataObj ) { - return frameData.updateFrameData(rscDataObj); - } + boolean foundFrame = false; + boolean lastFrame = false; - // allow this to be overridden if derived class needs to - protected boolean preProcessFrameUpdate() { - return true; - } + // loop through the frames and add this record to all that it time + // matches to + // + for (AbstractFrameData frameData : frameDataMap.values()) { + if (frameData != null) { + if (frameData.isRscDataObjInFrame(rscDataObj)) { + if (addRscDataToFrame(frameData, rscDataObj)) { + // frameData.setPopulated(true); + foundFrame = true; + } - // allow this to be overridden if derived class needs to - protected boolean postProcessFrameUpdate() { - return true; - } + if (frameData == frameDataMap.lastEntry().getValue()) { + lastFrame = true; + } + } + } + } - protected abstract AbstractFrameData createNewFrame( DataTime frameTime, - int frameInterval ); + // if not in any frames (or if in the last frame) and if updating + // and if this the data is + // newer than the latest frame then cache the data for auto update. + // NOTE: this will 'drop' (not cache) data from the initial query + // that doesn't match the + // selected timeline which means that if the user later enables + // auto-update, this data will + // not be loaded as part of the auto-update. This is by design but + // could be changed if the + // user wants a different behaviour.) + // NOTE: if the data is in the last frame then it may still + // potentially match the next frame + // when an update occurs. (WAPITA) (Note2: the auto update code is + // written to update a frame even + // if it is not the last frame. (ie. data is received out of order + // for some reason.) but this + // will cause any non-dominant data to not be displayed on these + // frames because we are only + // checking for the last frame here.) + long dataTimeMs = getDataTimeMs(rscDataObj);// rscDataObj.getDataTime().getValidTime().getTime().getTime(); - // This method can be used as a convenience if the MetadataMap constraints are - // all that is needed to query the data. - public void queryRecords() throws VizException { + if (timeMatcher.isAutoUpdateable()) { - HashMap queryList = new HashMap( - resourceData.getMetadataMap()); + if ((!foundFrame && autoUpdateReady && dataTimeMs > frameDataMap + .firstKey()) || lastFrame) { + // if there is the possibility of auto updating (if the + // dominant resource + // is a satellite or radar image) then store off the data in + // the autoUpdateCache + // and then update the timeline if auto update is enabled.. + // + autoUpdateCache.add(rscDataObj); - LayerProperty prop = new LayerProperty(); - prop.setDesiredProduct(ResourceType.PLAN_VIEW); - prop.setEntryQueryParameters(queryList, false); - prop.setNumberOfImages(15000); // TODO: max # records ?? should we cap - // this ? - String script = null; - script = ScriptCreator.createScript(prop); + // if this is the dominantResource, and this data is from a + // data update alert then + // determine if a new frame is needed. + // + if (isDominantResource() && autoUpdateReady) { + newFrameTimesList.addAll(timeMatcher + .determineNewFrameTimes(rscDataObj + .getDataTime())); + } + } + } + } - if (script == null) - return; + // allow resources to post-process the data after it is added to the + // frames + postProcessFrameUpdate(); - Object[] pdoList = Connector.getInstance().connect(script, null, 60000); + autoUpdateReady = false; - for (Object pdo : pdoList) { - for( IRscDataObject dataObject : processRecord( pdo ) ) { - newRscDataObjsQueue.add(dataObject); - } - } + // if there is data in the auto update cache and if auto update is now + // enabled + // and if this is the dominant resource for the timeline then we need to + // update the timeline and process the data in the cache. + // - // - setAllFramesAsPopulated(); - } + // timeMatcher.updateTimeline(newFrameTimesList); - public boolean isDominantResource( ) { - NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + if (!newFrameTimesList.isEmpty() && getDescriptor().isAutoUpdate()) { - if( timeMatcher != null && - timeMatcher.getDominantResourceName() != null ) { - - String domRscName = timeMatcher.getDominantResourceName().toString(); - - if( domRscName.equals( getResourceData().getResourceName().toString() ) ) { - return true; - } - } - - return false; - } - protected void removeAllNewDataObjects() { - newRscDataObjsQueue.clear(); - } - - // Don't think this should be called for NatlCntrs resources...? - // if so then need to lookup the frame and remove it - @Override - public final void remove( DataTime dataTime ) { -// super.remove( dataTime ); - // remove the given frame and call dispose - // will the system call this for each resource removed? Need all resources to be in sync. - } + // update the list of times in the timeMatcher. + // this will then trigger the descriptor to update its datatimes and + // notify its resources (including this one) to create and update + // the frames + timeMatcher.updateTimeline(newFrameTimesList); - // let the resource refresh and do anything else it needs to do after - // modifying its attributes. - // override if the resource needs this - public void resourceAttrsModified() { - // Do nothing - } - - // override this if needed - @Override + newFrameTimesList.clear(); + // advance to the new last frame (per legacy; could change)... + descriptor.getFrameCoordinator().changeFrame( + IFrameCoordinator.FrameChangeOperation.LAST, + IFrameCoordinator.FrameChangeMode.TIME_ONLY); + // ...and make sure it gets painted + issueRefresh(); + } + + return true; + } + + // break out from updateFrames to allow subclasses to override if needed. + protected boolean addRscDataToFrame(AbstractFrameData frameData, + IRscDataObject rscDataObj) { + return frameData.updateFrameData(rscDataObj); + } + + // allow this to be overridden if derived class needs to + protected boolean preProcessFrameUpdate() { + return true; + } + + // allow this to be overridden if derived class needs to + protected boolean postProcessFrameUpdate() { + return true; + } + + protected abstract AbstractFrameData createNewFrame(DataTime frameTime, + int frameInterval); + + // This method can be used as a convenience if the MetadataMap constraints + // are + // all that is needed to query the data. + public void queryRecords() throws VizException { + + HashMap queryList = new HashMap( + resourceData.getMetadataMap()); + + LayerProperty prop = new LayerProperty(); + prop.setDesiredProduct(ResourceType.PLAN_VIEW); + prop.setEntryQueryParameters(queryList, false); + prop.setNumberOfImages(15000); // TODO: max # records ?? should we cap + // this ? + String script = null; + script = ScriptCreator.createScript(prop); + + if (script == null) + return; + + Object[] pdoList = Connector.getInstance().connect(script, null, 60000); + + for (Object pdo : pdoList) { + for (IRscDataObject dataObject : processRecord(pdo)) { + newRscDataObjsQueue.add(dataObject); + } + } + + // + setAllFramesAsPopulated(); + } + + public boolean isDominantResource() { + NCTimeMatcher timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + + if (timeMatcher != null + && timeMatcher.getDominantResourceName() != null) { + + String domRscName = timeMatcher.getDominantResourceName() + .toString(); + + if (domRscName.equals(getResourceData().getResourceName() + .toString())) { + return true; + } + } + + return false; + } + + protected void removeAllNewDataObjects() { + newRscDataObjsQueue.clear(); + } + + // Don't think this should be called for NatlCntrs resources...? + // if so then need to lookup the frame and remove it + @Override + public final void remove(DataTime dataTime) { + // super.remove( dataTime ); + // remove the given frame and call dispose + // will the system call this for each resource removed? Need all + // resources to be in sync. + } + + // let the resource refresh and do anything else it needs to do after + // modifying its attributes. + // override if the resource needs this + public void resourceAttrsModified() { + // Do nothing + } + + // override this if needed + @Override protected void disposeInternal() { - for( AbstractFrameData frameData : frameDataMap.values() ) { - frameData.dispose(); - } + for (AbstractFrameData frameData : frameDataMap.values()) { + frameData.dispose(); + } } - - protected void clearFrames() { - for( AbstractFrameData frameData : frameDataMap.values() ) { - frameData.dispose(); - } - } - + + protected void clearFrames() { + for (AbstractFrameData frameData : frameDataMap.values()) { + frameData.dispose(); + } + } + @Override public String toString() { return this.resourceData.toString(); } - + // added since WarnResource gets null pointers in processNewRscDataList() - protected long getDataTimeMs(IRscDataObject rscDataObj) { - return rscDataObj.getDataTime().getValidTime().getTime().getTime(); - - } - - // set the populated flag in all frames - // this is done when the data for all frames has been queried at one time - // as opposed to populating as each frame is displayed. - // - protected void setAllFramesAsPopulated() { - for( AbstractFrameData frameData : frameDataMap.values() ) { - frameData.setPopulated(true); - } - } + protected long getDataTimeMs(IRscDataObject rscDataObj) { + return rscDataObj.getDataTime().getValidTime().getTime().getTime(); + + } + + // set the populated flag in all frames + // this is done when the data for all frames has been queried at one time + // as opposed to populating as each frame is displayed. + // + protected void setAllFramesAsPopulated() { + for (AbstractFrameData frameData : frameDataMap.values()) { + frameData.setPopulated(true); + } + } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResourceData.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResourceData.java index 7610f46572..bf4a9c2c79 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResourceData.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/AbstractNatlCntrsResourceData.java @@ -1,27 +1,25 @@ package gov.noaa.nws.ncep.viz.resources; +import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; +import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.resources.attributes.ResourceAttrSet; +import gov.noaa.nws.ncep.viz.resources.attributes.ResourceAttrSet.RscAttrValue; +import gov.noaa.nws.ncep.viz.resources.attributes.ResourceExtPointMngr; +import gov.noaa.nws.ncep.viz.resources.attributes.ResourceExtPointMngr.ResourceParamInfo; +import gov.noaa.nws.ncep.viz.resources.attributes.ResourceExtPointMngr.ResourceParamType; +import gov.noaa.nws.ncep.viz.resources.manager.ResourceName; +import gov.noaa.nws.ncep.viz.resources.manager.ResourceName.ResourceNameAdapter; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; -import java.util.Set; - -import gov.noaa.nws.ncep.viz.common.RGBColorAdapter; -import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; -import gov.noaa.nws.ncep.viz.resources.attributes.ResourceAttrSet; -import gov.noaa.nws.ncep.viz.resources.attributes.ResourceExtPointMngr; -import gov.noaa.nws.ncep.viz.resources.attributes.ResourceAttrSet.RscAttrValue; -import gov.noaa.nws.ncep.viz.resources.attributes.ResourceExtPointMngr.ResourceParamInfo; -import gov.noaa.nws.ncep.viz.resources.attributes.ResourceExtPointMngr.ResourceParamType; -import gov.noaa.nws.ncep.viz.resources.manager.ResourceName; -import gov.noaa.nws.ncep.viz.resources.manager.ResourceName.ResourceNameAdapter; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; import org.eclipse.swt.graphics.RGB; @@ -31,20 +29,22 @@ import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.rsc.AbstractResourceData; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.LoadProperties; -import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; /** - * This is the abstract class for all Natl Cntrs (non-requestable) resources. It is very similar to - * the AbstractNatlCntrsRequestableResourceData class with the only real difference being that it - * extends AbstractResourceData instead of AbstractRequestableResourceData. - * The main purpose of this class is to manage the resource's attributes which are stored in a - * named ResourceAttrSet (currently the .prm files) The values in the attrSet can be loaded to and - * from the ResourceData. The edit Attributes dialog uses this to get the attribute values from - * the resource. When an RBD is being created the attribute values are stored in the .prm file and - * in a ResourceData and both are written out to the RBD file along with a flag indicating whether - * the attribute values were edited from the original named attribute set. When the RBD is loaded - * the resource uses this flag to use either the values in the .prm file at load time (which may - * have changed from when the RBD was created) or from the unmarshalled resource. + * This is the abstract class for all Natl Cntrs (non-requestable) resources. It + * is very similar to the AbstractNatlCntrsRequestableResourceData class with + * the only real difference being that it extends AbstractResourceData instead + * of AbstractRequestableResourceData. The main purpose of this class is to + * manage the resource's attributes which are stored in a named ResourceAttrSet + * (currently the .prm files) The values in the attrSet can be loaded to and + * from the ResourceData. The edit Attributes dialog uses this to get the + * attribute values from the resource. When an RBD is being created the + * attribute values are stored in the .prm file and in a ResourceData and both + * are written out to the RBD file along with a flag indicating whether the + * attribute values were edited from the original named attribute set. When the + * RBD is loaded the resource uses this flag to use either the values in the + * .prm file at load time (which may have changed from when the RBD was created) + * or from the unmarshalled resource. * *
  * 
@@ -59,340 +59,369 @@ import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
  * Feb 22, 2013    972     ghull       getSupportedDisplayTypes
  * 
  * 
- * * + * + * * + * * @author ghull * @version 1.0 */ @XmlAccessorType(XmlAccessType.NONE) -public abstract class AbstractNatlCntrsResourceData extends AbstractResourceData - implements INatlCntrsResourceData, ISerializableObject{ +public abstract class AbstractNatlCntrsResourceData extends + AbstractResourceData implements INatlCntrsResourceData, + ISerializableObject { + + @XmlElement + @XmlJavaTypeAdapter(RGBColorAdapter.class) + protected RGB legendColor; + + // if true then the attribute values are stored in the member variables, if + // false then + // the attribute values are stored in the rscAttrSet. + @XmlAttribute + protected boolean isEdited; + + protected ResourceExtPointMngr rscExtPointMngr = null; + + // the full name/path of the resource with its category, sub-category... + @XmlAttribute + @XmlJavaTypeAdapter(ResourceNameAdapter.class) + ResourceName resourceName = null; + + @XmlElement + protected String resourceVersion = ""; // TODO : not implemented + + private AbstractVizResource ncRsc; - @XmlElement - @XmlJavaTypeAdapter(RGBColorAdapter.class) - protected RGB legendColor; - - // if true then the attribute values are stored in the member variables, if false then - // the attribute values are stored in the rscAttrSet. - @XmlAttribute - protected boolean isEdited; - - protected ResourceExtPointMngr rscExtPointMngr = null; - - // the full name/path of the resource with its category, sub-category... - @XmlAttribute - @XmlJavaTypeAdapter(ResourceNameAdapter.class) - ResourceName resourceName = null; - - @XmlElement - protected String resourceVersion=""; // TODO : not implemented - - private AbstractVizResource ncRsc; - public AbstractNatlCntrsResourceData() { super(); isEdited = false; resourceVersion = null; ncRsc = null; - legendColor = new RGB(255,255,255); + legendColor = new RGB(255, 255, 255); rscExtPointMngr = ResourceExtPointMngr.getInstance(); } - // implement here as a convienience since almost all of our + // implement here as a convienience since almost all of our // resources are on map based displays. Other resources - // that are written to draw to differendt display types will + // that are written to draw to differendt display types will // need to override this. - public NcDisplayType[] getSupportedDisplayTypes() { - return new NcDisplayType[] { NcDisplayType.NMAP_DISPLAY }; - } - - // Version can be used to test whether an RBD was created with an older version of the resource - // Currently this is not enforced or implemented by any of the resources. - public String getResourceVersion() { - return resourceVersion; - } - - public void setResourceVersion(String resourceVersion) { - this.resourceVersion = resourceVersion; - } - - // get/set for isEdited - public void setIsEdited( boolean e ) { - isEdited = e; + public NcDisplayType[] getSupportedDisplayTypes() { + return new NcDisplayType[] { NcDisplayType.NMAP_DISPLAY }; } - + + // Version can be used to test whether an RBD was created with an older + // version of the resource + // Currently this is not enforced or implemented by any of the resources. + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + // get/set for isEdited + public void setIsEdited(boolean e) { + isEdited = e; + } + public boolean getIsEdited() { - return isEdited; - } + return isEdited; + } - public final ResourceName getResourceName() { - return resourceName; - } + public final ResourceName getResourceName() { + return resourceName; + } - public void setResourceName( ResourceName rscName ) { - resourceName = new ResourceName( rscName ); - } + public void setResourceName(ResourceName rscName) { + resourceName = new ResourceName(rscName); + } @Override - public AbstractVizResource construct( LoadProperties loadProperties, IDescriptor descriptor) - throws VizException { - AbstractVizResource rsc = constructResource( loadProperties, descriptor ); - - // store off the resource. Currently this is done only to be able to update the color - // capability when the color attribute is changed. - if( rsc instanceof INatlCntrsResource ) { - // The current design assumes that each ResourceData will only create one Resource. If this - // needs to change then we will either need to store a list of ncRscs or create a new - // AbstractNatlCntrsResource class and put the color update code in it. - if( ncRsc != null ) { - System.out.println("Sanity Check: ncRsc != null. A ResourceData is attempting to construct "); - System.out.println(" a resource that already exists. "); - } - ncRsc = rsc; - } - else { - System.out.println("A NatlCntrsResourceData is constructing a non-NatlCntrs Resource???"); - } - - // if this resource was not edited (ie attribute values changed from the original values in - // the rscAttrSet) then get the values from the rscAttrSet and set the member variables with them. - // In other words, if the attribute values in the rscAttrSet were changed from the time when the - // RBD was created to now we will use the current values.) (This behaviour could be change to + public AbstractVizResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + AbstractVizResource rsc = constructResource(loadProperties, + descriptor); + + // store off the resource. Currently this is done only to be able to + // update the color + // capability when the color attribute is changed. + if (rsc instanceof INatlCntrsResource) { + // The current design assumes that each ResourceData will only + // create one Resource. If this + // needs to change then we will either need to store a list of + // ncRscs or create a new + // AbstractNatlCntrsResource class and put the color update code in + // it. + if (ncRsc != null) { + System.out + .println("Sanity Check: ncRsc != null. A ResourceData is attempting to construct "); + System.out.println(" a resource that already exists. "); + } + ncRsc = rsc; + } else { + System.out + .println("A NatlCntrsResourceData is constructing a non-NatlCntrs Resource???"); + } + + // if this resource was not edited (ie attribute values changed from the + // original values in + // the rscAttrSet) then get the values from the rscAttrSet and set the + // member variables with them. + // In other words, if the attribute values in the rscAttrSet were + // changed from the time when the + // RBD was created to now we will use the current values.) (This + // behaviour could be change to // only apply to the default attrSet if we wanted to.) // -// if( rscAttrSet == null && rscAttrSetName != null ) { -// rscAttrSet = new ResourceAttrSet( rscAttrSetName ); -// } -// -// if( rscAttrSet != null ) { -// if( isEdited ) { -// // if the attributes were edited then the values in rscAttrSet are different so update them -// // here. (Note: currently this is not required. We could instead just not create an attrSet.) -// // Or we might want to change the name to prevent inadvertant writing out of edited attributes to -// // the file.) -// getResourceAttrValues( rscAttrSet ); -// } -// -// // call setRscAttrSet instead of setResourceAttrValues since -// // setRscAttrSet may be overridden. This is the case for the overlayResourceGroup and -// // this is how the component maps for the group are updated with the attributes for the group. -// setRscAttrSet( rscAttrSet ); -// } + // if( rscAttrSet == null && rscAttrSetName != null ) { + // rscAttrSet = new ResourceAttrSet( rscAttrSetName ); + // } + // + // if( rscAttrSet != null ) { + // if( isEdited ) { + // // if the attributes were edited then the values in rscAttrSet are + // different so update them + // // here. (Note: currently this is not required. We could instead just + // not create an attrSet.) + // // Or we might want to change the name to prevent inadvertant writing + // out of edited attributes to + // // the file.) + // getResourceAttrValues( rscAttrSet ); + // } + // + // // call setRscAttrSet instead of setResourceAttrValues since + // // setRscAttrSet may be overridden. This is the case for the + // overlayResourceGroup and + // // this is how the component maps for the group are updated with the + // attributes for the group. + // setRscAttrSet( rscAttrSet ); + // } - return rsc; + return rsc; } - - - public abstract AbstractVizResource constructResource( LoadProperties loadProperties, - IDescriptor descriptor) throws VizException ; - // get a list of the defined attributes for this resource and - // - public ResourceAttrSet getRscAttrSet() { - - HashMap rscImplParamInfo = - rscExtPointMngr.getParameterInfoForRscImplementation( getResourceName() ); - - if( rscImplParamInfo == null ) { - System.out.println("Couldn't find rsc impl parameter info for "+getResourceName() ); - return null; - } + public abstract AbstractVizResource constructResource( + LoadProperties loadProperties, IDescriptor descriptor) + throws VizException; - ResourceAttrSet rscAttrSet = new ResourceAttrSet( - resourceName.getRscAttrSetName() ); + // get a list of the defined attributes for this resource and + // + public ResourceAttrSet getRscAttrSet() { - for( ResourceParamInfo prmInfo : rscImplParamInfo.values() ) { - - if( prmInfo.getParamType() != ResourceParamType.EDITABLE_ATTRIBUTE ) { - continue; - } + HashMap rscImplParamInfo = rscExtPointMngr + .getParameterInfoForRscImplementation(getResourceName()); - Method[] mthds = this.getClass().getDeclaredMethods(); - String attrName = prmInfo.getParamName(); + if (rscImplParamInfo == null) { + System.out.println("Couldn't find rsc impl parameter info for " + + getResourceName()); + return null; + } - String getMthdName = "get"+attrName.substring(0,1).toUpperCase() + - attrName.substring(1); + ResourceAttrSet rscAttrSet = new ResourceAttrSet( + resourceName.getRscAttrSetName()); - for( Method m : mthds ) { - if( m.getName().equals( getMthdName ) ) { - Class[] params = m.getParameterTypes(); - Class rtype = m.getReturnType(); + for (ResourceParamInfo prmInfo : rscImplParamInfo.values()) { -// This would be a nice sanity check but I would have to go back and change all ints and booleans -// in the getters and setters for old resources even though they are compatible with the defined classes -// if( rtype != attrInfo.getAttrClass() ) { -// System.out.println("Warning: Attribute "+attrName +" is not defined\n"+ -// "as correct type:" +rtype.getName() + " != " + -// attrInfo.getAttrClass().getName() ); -// } + if (prmInfo.getParamType() != ResourceParamType.EDITABLE_ATTRIBUTE) { + continue; + } - if( params.length == 0 ) { - Object attrVal=null; - try { - attrVal = m.invoke( this ); + Method[] mthds = this.getClass().getDeclaredMethods(); + String attrName = prmInfo.getParamName(); - Constructor cc = rtype.getConstructor( rtype ); - if( cc != null ) { - attrVal = cc.newInstance( attrVal ); - } + String getMthdName = "get" + attrName.substring(0, 1).toUpperCase() + + attrName.substring(1); - rscAttrSet.setAttrValue( attrName, attrVal ); + for (Method m : mthds) { + if (m.getName().equals(getMthdName)) { + Class[] params = m.getParameterTypes(); + Class rtype = m.getReturnType(); - } catch (NoSuchMethodException e) { - // if there is no copy constructor go ahead and set - // the attribute value - rscAttrSet.setAttrValue( attrName, attrVal ); + // This would be a nice sanity check but I would have to go + // back and change all ints and booleans + // in the getters and setters for old resources even though + // they are compatible with the defined classes + // if( rtype != attrInfo.getAttrClass() ) { + // System.out.println("Warning: Attribute "+attrName + // +" is not defined\n"+ + // "as correct type:" +rtype.getName() + " != " + + // attrInfo.getAttrClass().getName() ); + // } - } catch( IllegalAccessException iae ) { - System.out.println(iae.getMessage()); - } catch( IllegalArgumentException iae ) { - System.out.println(iae.getMessage()); - } catch( InvocationTargetException ite ) { - System.out.println(ite.getMessage()); - } catch( ClassCastException cce ) { - System.out.println(cce.getMessage()); - } catch (SecurityException e) { - System.out.println(e.getMessage()); - } catch (InstantiationException e) { - System.out.println(e.getMessage()); - } - } - } - } - } - - return rscAttrSet; - } + if (params.length == 0) { + Object attrVal = null; + try { + attrVal = m.invoke(this); + Constructor cc = rtype.getConstructor(rtype); + if (cc != null) { + attrVal = cc.newInstance(attrVal); + } - // the rscAttrSet should only contain attributes defined for this resource. - // - public boolean setRscAttrSet( ResourceAttrSet newRscAttrSet ) { - if( newRscAttrSet == null ) { - return false; - } + rscAttrSet.setAttrValue(attrName, attrVal); - HashMap rscImplParamInfo = - rscExtPointMngr.getParameterInfoForRscImplementation( getResourceName() ); - - if( rscImplParamInfo == null ) { - System.out.println("Couldn't find rsc impl parameter info for "+getResourceName() ); - return false; - } + } catch (NoSuchMethodException e) { + // if there is no copy constructor go ahead and set + // the attribute value + rscAttrSet.setAttrValue(attrName, attrVal); - // loop thru the attributes and use Java Bean utils to set the attributes on the resource - for( ResourceParamInfo prmInfo : rscImplParamInfo.values() ) { + } catch (IllegalAccessException iae) { + System.out.println(iae.getMessage()); + } catch (IllegalArgumentException iae) { + System.out.println(iae.getMessage()); + } catch (InvocationTargetException ite) { + System.out.println(ite.getMessage()); + } catch (ClassCastException cce) { + System.out.println(cce.getMessage()); + } catch (SecurityException e) { + System.out.println(e.getMessage()); + } catch (InstantiationException e) { + System.out.println(e.getMessage()); + } + } + } + } + } - if( prmInfo.getParamType() != ResourceParamType.EDITABLE_ATTRIBUTE ) { - continue; - } + return rscAttrSet; + } - String attrName = prmInfo.getParamName(); - - // make sure that this attrSet has this attributeName - if( !newRscAttrSet.hasAttrName(attrName) ) { - continue; - } - - RscAttrValue rscAttr = newRscAttrSet.getRscAttr( attrName ); - Object attrValue = rscAttr.getAttrValue(); - Class attrClass = rscAttr.getAttrClass(); + // the rscAttrSet should only contain attributes defined for this resource. + // + public boolean setRscAttrSet(ResourceAttrSet newRscAttrSet) { + if (newRscAttrSet == null) { + return false; + } - if( attrClass != prmInfo.getParamClass() ) { - System.out.println("Unable to set Attribute "+attrName+" because it is defined as "+ - " the wrong type: "+attrClass.getName()+" != "+ - prmInfo.getParamClass().getName() ); - continue; - } - else if( attrValue == null ) { - continue; - } + HashMap rscImplParamInfo = rscExtPointMngr + .getParameterInfoForRscImplementation(getResourceName()); - String setMthdName = "set"+attrName.substring(0,1).toUpperCase() + - attrName.substring(1); + if (rscImplParamInfo == null) { + System.out.println("Couldn't find rsc impl parameter info for " + + getResourceName()); + return false; + } - Method[] mthds = this.getClass().getDeclaredMethods(); + // loop thru the attributes and use Java Bean utils to set the + // attributes on the resource + for (ResourceParamInfo prmInfo : rscImplParamInfo.values()) { - for( Method m : mthds ) { - if( m.getName().equals( setMthdName ) ) { - Class[] params = m.getParameterTypes(); - Class rtype = m.getReturnType(); - - // This would be a nice sanity check but I would have to go back and change all ints and booleans - // in the getters and setters for old resources even though they are compatible with the defined classes -// if( params[0].getClass() != attrInfo.getAttrClass() || -// params.length != 1) { -// System.out.println("Error setting rsc attr "+attrName+" : setter class " + -// "has incompatible argument."); -// System.out.println("Warning: Attribute "+attrName +" is not defined\n"+ -// "as correct type:" +rtype.getName() + " != " + -// attrInfo.getAttrClass().getName() ); -// continue; -// } + if (prmInfo.getParamType() != ResourceParamType.EDITABLE_ATTRIBUTE) { + continue; + } - try { - m.invoke( this, attrValue ); - } catch( IllegalAccessException iae ) { - System.out.println(iae.getMessage()); - } catch( IllegalArgumentException iae ) { - System.out.println(iae.getMessage()); - } catch( InvocationTargetException ite ) { - System.out.println(ite.getMessage()); - } catch( ClassCastException cce ) { - System.out.println(cce.getMessage()); - } - } - } - } - - if( ncRsc != null ) { - ((INatlCntrsResource)ncRsc).resourceAttrsModified(); - } + String attrName = prmInfo.getParamName(); + + // make sure that this attrSet has this attributeName + if (!newRscAttrSet.hasAttrName(attrName)) { + continue; + } + + RscAttrValue rscAttr = newRscAttrSet.getRscAttr(attrName); + Object attrValue = rscAttr.getAttrValue(); + Class attrClass = rscAttr.getAttrClass(); + + if (attrClass != prmInfo.getParamClass()) { + System.out.println("Unable to set Attribute " + attrName + + " because it is defined as " + " the wrong type: " + + attrClass.getName() + " != " + + prmInfo.getParamClass().getName()); + continue; + } else if (attrValue == null) { + continue; + } + + String setMthdName = "set" + attrName.substring(0, 1).toUpperCase() + + attrName.substring(1); + + Method[] mthds = this.getClass().getDeclaredMethods(); + + for (Method m : mthds) { + if (m.getName().equals(setMthdName)) { + Class[] params = m.getParameterTypes(); + Class rtype = m.getReturnType(); + + // This would be a nice sanity check but I would have to go + // back and change all ints and booleans + // in the getters and setters for old resources even though + // they are compatible with the defined classes + // if( params[0].getClass() != attrInfo.getAttrClass() || + // params.length != 1) { + // System.out.println("Error setting rsc attr "+attrName+" : setter class " + // + + // "has incompatible argument."); + // System.out.println("Warning: Attribute "+attrName + // +" is not defined\n"+ + // "as correct type:" +rtype.getName() + " != " + + // attrInfo.getAttrClass().getName() ); + // continue; + // } + + try { + m.invoke(this, attrValue); + } catch (IllegalAccessException iae) { + System.out.println(iae.getMessage()); + } catch (IllegalArgumentException iae) { + System.out.println(iae.getMessage()); + } catch (InvocationTargetException ite) { + System.out.println(ite.getMessage()); + } catch (ClassCastException cce) { + System.out.println(cce.getMessage()); + } + } + } + } + + if (ncRsc != null) { + ((INatlCntrsResource) ncRsc).resourceAttrsModified(); + } + + return true; + } - return true; - } - @Override public void update(Object updateData) { // Do nothing version for those resources that don't need this method } - public void setLegendColor( RGB legClr ) { - legendColor = legClr; + public void setLegendColor(RGB legClr) { + legendColor = legClr; } - + public RGB getLegendColor() { - return legendColor; + return legendColor; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AbstractNatlCntrsResourceData other = (AbstractNatlCntrsResourceData) obj; + if (isEdited != other.isEdited) + return false; + if (legendColor == null) { + if (other.legendColor != null) + return false; + } else if (!legendColor.equals(other.legendColor)) + return false; + if (resourceName == null) { + if (other.resourceName != null) + return false; + } else if (!resourceName.equals(other.resourceName)) + return false; + if (resourceVersion == null) { + if (other.resourceVersion != null) + return false; + } else if (!resourceVersion.equals(other.resourceVersion)) + return false; + return true; } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AbstractNatlCntrsResourceData other = (AbstractNatlCntrsResourceData) obj; - if (isEdited != other.isEdited) - return false; - if (legendColor == null) { - if (other.legendColor != null) - return false; - } else if (!legendColor.equals(other.legendColor)) - return false; - if (resourceName == null) { - if (other.resourceName != null) - return false; - } else if (!resourceName.equals(other.resourceName)) - return false; - if (resourceVersion == null) { - if (other.resourceVersion != null) - return false; - } else if (!resourceVersion.equals(other.resourceVersion)) - return false; - return true; - } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java index 99cbd283e3..440ec8bcce 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/AbstractRBD.java @@ -71,6 +71,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * 05/14/13 #862 Greg Hull implement INatlCntrsPaneManager * 11/21/13 #1066 Greg Hull save off Native gridGeometries during clone() * 10/29/13 #2491 bsteffen Use custom JAXB context instead of SerializationUtil. + * 05/15/2014 #1131 Quan Zhou Added GRAPH_DISPLAY. * * * @author ghull @@ -78,7 +79,8 @@ import com.raytheon.viz.ui.editor.AbstractEditor; */ @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public abstract class AbstractRBD implements INatlCntrsPaneManager, Comparable> { +public abstract class AbstractRBD + implements INatlCntrsPaneManager, Comparable> { private static JAXBManager jaxb; @XmlElement @@ -152,7 +154,8 @@ public abstract class AbstractRBD implement this.autoUpdate = autoUpdate; for (T disp : getDisplays()) { if (disp != null) { - ((INatlCntrsDescriptor) disp.getDescriptor()).setAutoUpdate(autoUpdate); + ((INatlCntrsDescriptor) disp.getDescriptor()) + .setAutoUpdate(autoUpdate); } } } @@ -206,7 +209,8 @@ public abstract class AbstractRBD implement @Override public IPaneLayoutable getPane(INcPaneID pid) { - if (paneLayout.containsPaneId(pid) && paneLayout.getPaneIndex(pid) < displays.length) { + if (paneLayout.containsPaneId(pid) + && paneLayout.getPaneIndex(pid) < displays.length) { T pane = displays[paneLayout.getPaneIndex(pid)]; @@ -255,7 +259,8 @@ public abstract class AbstractRBD implement // ncEditor = null; setPaneLayout(paneLayout); try { - displays = (T[]) NcDisplayMngr.createDisplaysForNcDisplayType(this, paneLayout); + displays = (T[]) NcDisplayMngr.createDisplaysForNcDisplayType(this, + paneLayout); } catch (VizException e) { System.out.println(e.getMessage()); } @@ -263,7 +268,8 @@ public abstract class AbstractRBD implement // protected abstract T[] createDisplays( int num ); - public static AbstractRBD clone(AbstractRBD rbdBndl) throws VizException { + public static AbstractRBD clone(AbstractRBD rbdBndl) + throws VizException { try { NCTimeMatcher tm = new NCTimeMatcher(rbdBndl.getTimeMatcher()); @@ -285,13 +291,17 @@ public abstract class AbstractRBD implement NcGridGeometryAdapter geomAdapter = new NcGridGeometryAdapter(); for (AbstractRenderableDisplay disp : rbdBndl.getDisplays()) { - GeneralGridGeometry geom = disp.getDescriptor().getGridGeometry(); + GeneralGridGeometry geom = disp.getDescriptor() + .getGridGeometry(); - if (geom.getEnvelope().getCoordinateReferenceSystem().getName().toString().startsWith("MCIDAS")) { + if (geom.getEnvelope().getCoordinateReferenceSystem().getName() + .toString().startsWith("MCIDAS")) { GridGeometrySerialized ggs = geomAdapter.marshal(geom); - ggsMap.put(((INatlCntrsRenderableDisplay) disp).getPaneId().toString(), ggs); - dispMap.put(((INatlCntrsRenderableDisplay) disp).getPaneId().toString(), disp); + ggsMap.put(((INatlCntrsRenderableDisplay) disp).getPaneId() + .toString(), ggs); + dispMap.put(((INatlCntrsRenderableDisplay) disp) + .getPaneId().toString(), disp); // DefaultProjectedCRS pCRS = // (DefaultProjectedCRS)geom.getCoordinateReferenceSystem(); // String crsWkt = pCRS.toWKT(); @@ -299,18 +309,25 @@ public abstract class AbstractRBD implement // ((INatlCntrsRenderableDisplay)disp).getPaneId().toString(), // crsWkt ); // something valid as a placeholder.... - disp.getDescriptor().setGridGeometry(PredefinedAreaFactory.getDefaultPredefinedAreaForDisplayType(rbdBndl.getDisplayType()).getGridGeometry()); + disp.getDescriptor().setGridGeometry( + PredefinedAreaFactory + .getDefaultPredefinedAreaForDisplayType( + rbdBndl.getDisplayType()) + .getGridGeometry()); } } - getJaxbManager().marshalToXmlFile(rbdBndl, tempRbdFile.getAbsolutePath()); + getJaxbManager().marshalToXmlFile(rbdBndl, + tempRbdFile.getAbsolutePath()); AbstractRBD clonedRbd = getRbd(tempRbdFile); for (AbstractRenderableDisplay disp : clonedRbd.getDisplays()) { - String ggsKey = ((INatlCntrsRenderableDisplay) disp).getPaneId().toString(); + String ggsKey = ((INatlCntrsRenderableDisplay) disp) + .getPaneId().toString(); if (ggsMap.containsKey(ggsKey)) { - GeneralGridGeometry geom = geomAdapter.unmarshal(ggsMap.get(ggsKey)); + GeneralGridGeometry geom = geomAdapter.unmarshal(ggsMap + .get(ggsKey)); disp.getDescriptor().setGridGeometry(geom); // another copy (should we save the original and set it @@ -348,7 +365,8 @@ public abstract class AbstractRBD implement } catch (JAXBException e) { throw new VizException(e); } catch (VizException e) { - throw new VizException("Error loading rbd " + rbdBndl.rbdName + " :" + e.getMessage()); + throw new VizException("Error loading rbd " + rbdBndl.rbdName + + " :" + e.getMessage()); } catch (IOException e) { // from createTempFile throw new VizException(e); } catch (Exception e) { @@ -356,7 +374,8 @@ public abstract class AbstractRBD implement } } - public static AbstractRBD createEmptyRbdForDisplayType(NcDisplayType dispType, NcPaneLayout pLayout) throws VizException { + public static AbstractRBD createEmptyRbdForDisplayType( + NcDisplayType dispType, NcPaneLayout pLayout) throws VizException { AbstractRBD rbd = null; switch (dispType) { @@ -371,6 +390,10 @@ public abstract class AbstractRBD implement rbd = new SolarRBD(pLayout); rbd.setRbdName("Solar"); break; + case GRAPH_DISPLAY: + rbd = new GraphRBD(pLayout); + rbd.setRbdName("Graph"); + break; } rbd.setIsDefaultRbd(true); @@ -381,15 +404,19 @@ public abstract class AbstractRBD implement } private void createDisplays() throws VizException { - displays = (T[]) NcDisplayMngr.createDisplaysForNcDisplayType(this, getPaneLayout()); + displays = (T[]) NcDisplayMngr.createDisplaysForNcDisplayType(this, + getPaneLayout()); } - public static AbstractRBD createRbdFromEditor(AbstractEditor ncEditor) throws VizException { + public static AbstractRBD createRbdFromEditor(AbstractEditor ncEditor) + throws VizException { if (ncEditor == null) { return null; } - AbstractRBD rbd = createEmptyRbdForDisplayType(NcEditorUtil.getNcDisplayType(ncEditor), (NcPaneLayout) NcEditorUtil.getPaneLayout(ncEditor)); + AbstractRBD rbd = createEmptyRbdForDisplayType( + NcEditorUtil.getNcDisplayType(ncEditor), + (NcPaneLayout) NcEditorUtil.getPaneLayout(ncEditor)); rbd.initRbdFromEditor(ncEditor); @@ -418,10 +445,12 @@ public abstract class AbstractRBD implement geoSyncedPanes = NcEditorUtil.arePanesGeoSynced(ncEditor); autoUpdate = NcEditorUtil.getAutoUpdate(ncEditor); - displays = (T[]) NcDisplayMngr.createDisplaysForNcDisplayType(this, NcEditorUtil.getPaneLayout(ncEditor)); + displays = (T[]) NcDisplayMngr.createDisplaysForNcDisplayType(this, + NcEditorUtil.getPaneLayout(ncEditor)); for (int paneIndx = 0; paneIndx < paneLayout.getNumberOfPanes(); paneIndx++) { - IDisplayPane pane = NcEditorUtil.getDisplayPane(ncEditor, paneLayout.createPaneId(paneIndx));// new NcPaneID(r, c)); + IDisplayPane pane = NcEditorUtil.getDisplayPane(ncEditor, + paneLayout.createPaneId(paneIndx));// new NcPaneID(r, c)); T rDispPane = (T) pane.getRenderableDisplay(); @@ -431,7 +460,8 @@ public abstract class AbstractRBD implement displays[paneIndx] = rDispPane; } - setTimeMatcher(new NCTimeMatcher((NCTimeMatcher) displays[0].getDescriptor().getTimeMatcher())); + setTimeMatcher(new NCTimeMatcher((NCTimeMatcher) displays[0] + .getDescriptor().getTimeMatcher())); } /** @@ -460,11 +490,13 @@ public abstract class AbstractRBD implement // public INatlCntrsRenderableDisplay getDisplayPane(INcPaneID pid) { if (!paneLayout.containsPaneId(pid)) { - System.out.println("NcMapRBD.getDisplayPane: pane id " + pid.toString() + " is out of range."); + System.out.println("NcMapRBD.getDisplayPane: pane id " + + pid.toString() + " is out of range."); return null; } // - return (INatlCntrsRenderableDisplay) displays[paneLayout.getPaneIndex(pid)]; + return (INatlCntrsRenderableDisplay) displays[paneLayout + .getPaneIndex(pid)]; } public abstract boolean addDisplayPane(T dispPane, NcPaneID pid); @@ -524,7 +556,8 @@ public abstract class AbstractRBD implement // TODO : change/move this to be able to get user-based default RBDs. // - public static AbstractRBD getDefaultRBD(NcDisplayType displayType) throws VizException { + public static AbstractRBD getDefaultRBD(NcDisplayType displayType) + throws VizException { String dfltRbdName = ""; @@ -539,18 +572,27 @@ public abstract class AbstractRBD implement // one. case NTRANS_DISPLAY: dfltRbdName = null; // NcPathConstants.DFLT_NTRANS_RBD; - return AbstractRBD.createEmptyRbdForDisplayType(displayType, new NcPaneLayout(1, 1)); + return AbstractRBD.createEmptyRbdForDisplayType(displayType, + new NcPaneLayout(1, 1)); case SOLAR_DISPLAY: dfltRbdName = null; // NcPathConstants.DFLT_SOLAR_RBD; - return AbstractRBD.createEmptyRbdForDisplayType(displayType, new NcPaneLayout(1, 1)); + return AbstractRBD.createEmptyRbdForDisplayType(displayType, + new NcPaneLayout(1, 1)); + + case GRAPH_DISPLAY: + dfltRbdName = null; + return AbstractRBD.createEmptyRbdForDisplayType(displayType, + new NcPaneLayout(1, 1)); default: - throw new VizException("Unable to find the default RBD name for " + displayType.toString()); + throw new VizException("Unable to find the default RBD name for " + + displayType.toString()); } File rbdFile = NcPathManager.getInstance().getStaticFile(dfltRbdName); if (rbdFile == null) { - throw new VizException("Unable to find the default RBD file for " + displayType.toString()); + throw new VizException("Unable to find the default RBD file for " + + displayType.toString()); } try { @@ -564,7 +606,8 @@ public abstract class AbstractRBD implement return clone(dfltRbd); } catch (Exception ve) { - throw new VizException("Error getting default RBD: " + ve.getMessage()); + throw new VizException("Error getting default RBD: " + + ve.getMessage()); } } @@ -577,7 +620,8 @@ public abstract class AbstractRBD implement // older version) // if (rbd.displays == null || rbd.displays.length == 0) { - throw new VizException("Error unmarshalling RBD: the renderable display list is null"); + throw new VizException( + "Error unmarshalling RBD: the renderable display list is null"); } // getInitialArea can't return null. // for( AbstractRenderableDisplay d : rbd.getDisplays() ) { @@ -611,7 +655,8 @@ public abstract class AbstractRBD implement * * @throws VizException */ - private static AbstractRBD unmarshalRBD(File fileName, Map variables) throws VizException { + private static AbstractRBD unmarshalRBD(File fileName, + Map variables) throws VizException { String s = null; try { FileReader fr = new FileReader(fileName); @@ -642,12 +687,15 @@ public abstract class AbstractRBD implement * * @throws VizException */ - private static AbstractRBD unmarshalRBD(String bundleStr, Map variables) throws VizException { + private static AbstractRBD unmarshalRBD(String bundleStr, + Map variables) throws VizException { try { - String substStr = VariableSubstitutionUtil.processVariables(bundleStr, variables); + String substStr = VariableSubstitutionUtil.processVariables( + bundleStr, variables); - AbstractRBD b = (AbstractRBD) getJaxbManager().unmarshalFromXml(substStr); + AbstractRBD b = (AbstractRBD) getJaxbManager() + .unmarshalFromXml(substStr); if (b == null) { System.out.println("Unmarshalled rbd file is not a valid RBD?"); @@ -726,16 +774,20 @@ public abstract class AbstractRBD implement * @throws JAXBException * if there are illegal JAXB annotations. */ - public static synchronized JAXBManager getJaxbManager() throws JAXBException { + public static synchronized JAXBManager getJaxbManager() + throws JAXBException { if (jaxb == null) { SubClassLocator locator = new SubClassLocator(); - Collection> classes = JAXBClassLocator.getJAXBClasses(locator, AbstractRBD.class); + Collection> classes = JAXBClassLocator.getJAXBClasses( + locator, AbstractRBD.class); locator.save(); Class[] jaxbClasses = new Class[classes.size() + 1]; classes.toArray(jaxbClasses); - /* Add JaxbDummyObject at the begining so properties are loaded - * correctly */ + /* + * Add JaxbDummyObject at the begining so properties are loaded + * correctly + */ jaxbClasses[jaxbClasses.length - 1] = jaxbClasses[0]; jaxbClasses[0] = JaxbDummyObject.class; @@ -746,7 +798,8 @@ public abstract class AbstractRBD implement public NCTimeMatcher getTimeMatcher() { if (timeMatcher == null) { - timeMatcher = (NCTimeMatcher) displays[0].getDescriptor().getTimeMatcher(); + timeMatcher = (NCTimeMatcher) displays[0].getDescriptor() + .getTimeMatcher(); } return timeMatcher; } @@ -761,7 +814,8 @@ public abstract class AbstractRBD implement if (disp != null) { disp.getDescriptor().setTimeMatcher(timeMatcher); - timeMatcher.addDescriptor((INatlCntrsDescriptor) disp.getDescriptor()); + timeMatcher.addDescriptor((INatlCntrsDescriptor) disp + .getDescriptor()); } } } @@ -777,10 +831,12 @@ public abstract class AbstractRBD implement for (int r = 0; r < rl.size(); r++) { ResourcePair rp = rl.get(r); if (rp.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { - AbstractNatlCntrsRequestableResourceData rscData = (AbstractNatlCntrsRequestableResourceData) rp.getResourceData(); + AbstractNatlCntrsRequestableResourceData rscData = (AbstractNatlCntrsRequestableResourceData) rp + .getResourceData(); ResourceName rscName = rscData.getResourceName(); - if (rscName.isForecastResource() && rscName.isLatestCycleTime()) { + if (rscName.isForecastResource() + && rscName.isLatestCycleTime()) { rscData.getAvailableDataTimes(); @@ -789,7 +845,9 @@ public abstract class AbstractRBD implement // to have to be able to handle this case. // if (rscName.isLatestCycleTime()) { - System.out.println("Unable to Resolve Latest cycle time for :" + rscName); + System.out + .println("Unable to Resolve Latest cycle time for :" + + rscName); } } } @@ -806,7 +864,8 @@ public abstract class AbstractRBD implement ResourceName domRscName = timeMatcher.getDominantResourceName(); - if (domRscName != null && domRscName.isValid() && timeMatcher.getDominantResource() == null) { + if (domRscName != null && domRscName.isValid() + && timeMatcher.getDominantResource() == null) { // loop thru the displays looking for the dominant resource // @@ -815,9 +874,11 @@ public abstract class AbstractRBD implement for (int r = 0; r < rl.size(); r++) { ResourcePair rp = rl.get(r); if (rp.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { - AbstractNatlCntrsRequestableResourceData rdata = (AbstractNatlCntrsRequestableResourceData) rp.getResourceData(); + AbstractNatlCntrsRequestableResourceData rdata = (AbstractNatlCntrsRequestableResourceData) rp + .getResourceData(); - if (domRscName.toString().equals(rdata.getResourceName().toString())) { + if (domRscName.toString().equals( + rdata.getResourceName().toString())) { timeMatcher.setDominantResourceData(rdata); return; diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/GraphRBD.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/GraphRBD.java new file mode 100644 index 0000000000..2ac9baf373 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/GraphRBD.java @@ -0,0 +1,60 @@ +package gov.noaa.nws.ncep.viz.resources.manager; + +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; +import gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesRenderableDisplay; +import gov.noaa.nws.ncep.viz.ui.display.NcPaneID; +import gov.noaa.nws.ncep.viz.ui.display.NcPaneLayout; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * Bundle for Natl Cntrs Resources + * + *
+ * 
+ *    SOFTWARE HISTORY
+ *   
+ *    Date         Ticket#     Engineer    Description
+ *    ------------ ----------  ----------- --------------------------
+ *    2014/03/26/   #      qzhou       Modified
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ +@XmlRootElement +@XmlType(name = "GraphRBD") +@XmlAccessorType(XmlAccessType.NONE) +public class GraphRBD extends AbstractRBD { + + public GraphRBD() { + super(); + } + + public GraphRBD(NcPaneLayout paneLayout) { + super(paneLayout); + } + + @Override + public boolean addDisplayPane(NCTimeSeriesRenderableDisplay dispPane, + NcPaneID pid) { + if (!paneLayout.containsPaneId(pid)) { + System.out.println("NcMapRBD.getDisplayPane: pane id " + + pid.toString() + " is out of range."); + return false; + } + + displays[paneLayout.getPaneIndex(pid)] = dispPane; + + // sync the descriptor's auto update with the value of this RBD. + ((INatlCntrsDescriptor) displays[paneLayout.getPaneIndex(pid)] + .getDescriptor()).setAutoUpdate(isAutoUpdate()); + + return true; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java index 7d05d5f5f1..6ac72be330 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceBndlLoader.java @@ -1,20 +1,17 @@ package gov.noaa.nws.ncep.viz.resources.manager; import gov.noaa.nws.ncep.viz.common.area.AreaName.AreaSource; -import gov.noaa.nws.ncep.viz.common.area.PredefinedArea; import gov.noaa.nws.ncep.viz.common.area.IGridGeometryProvider.ZoomLevelStrings; +import gov.noaa.nws.ncep.viz.common.area.PredefinedArea; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; import gov.noaa.nws.ncep.viz.common.display.NcDisplayName; import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; -import org.eclipse.swt.graphics.Rectangle; import gov.noaa.nws.ncep.viz.ui.display.NCMapDescriptor; -import gov.noaa.nws.ncep.viz.ui.display.NCMapRenderableDisplay; -import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; -import gov.noaa.nws.ncep.viz.ui.display.NcPaneLayout; import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; +import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; import gov.noaa.nws.ncep.viz.ui.display.NcPaneID; import java.util.Iterator; @@ -23,28 +20,27 @@ import java.util.concurrent.ConcurrentLinkedQueue; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.PixelExtent; import com.raytheon.uf.viz.core.VizApp; -import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; -import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.map.MapDescriptor; import com.raytheon.uf.viz.core.rsc.ResourceList; import com.raytheon.viz.ui.UiPlugin; import com.raytheon.viz.ui.editor.AbstractEditor; /** - * Resource Bundle Loader will load RBDs into new or existing map editors. - * (Note that this was originally designed to be in a separate thread but there was a problem - * with the thread loading the RBDs.) + * Resource Bundle Loader will load RBDs into new or existing map editors. (Note + * that this was originally designed to be in a separate thread but there was a + * problem with the thread loading the RBDs.) * - * TODO : This contains commented out code which will implement a Load Mode option that allows the user to either Append - * RBD resources to a display or to overwrite/replace resources already displayed. + * TODO : This contains commented out code which will implement a Load Mode + * option that allows the user to either Append RBD resources to a display or to + * overwrite/replace resources already displayed. * *
  * SOFTWARE HISTORY
@@ -71,298 +67,336 @@ import com.raytheon.viz.ui.editor.AbstractEditor;
  * 02/01/13     #972        Greg Hull     RbdBundleEditorWrapper doesn't need to be a generic
  * 02/12/13     #972        Greg Hull     NcDisplayType and NatlCntrsEditor
  * 11/26/13     #1078       Greg Hull     Size Of Image fix (PixelExtent constructor)
- *
+ * 
  * 
* * @version 1 */ -public class ResourceBndlLoader implements Runnable { // extends Job { +public class ResourceBndlLoader implements Runnable { // extends Job { + + private final class RbdBundleEditorWrapper { + private AbstractRBD rbdBundle; + + private AbstractEditor ncEditor; + + private Boolean replaceEditorNameWithRbdName; + + RbdBundleEditorWrapper(AbstractRBD theRbdBundle, AbstractEditor ed, + Boolean useRBDName) { + rbdBundle = theRbdBundle; + ncEditor = ed; + NcEditorUtil.setDisplayAvailable(ed, false); + replaceEditorNameWithRbdName = useRBDName; + } + + public AbstractRBD getRbdBundle() { + return rbdBundle; + } + + public AbstractEditor getNcEditor() { + return ncEditor; + } + + public Boolean useRbdNameForEditor() { + return replaceEditorNameWithRbdName; + } + } - private final class RbdBundleEditorWrapper { - private AbstractRBD rbdBundle; - private AbstractEditor ncEditor; - private Boolean replaceEditorNameWithRbdName; - - RbdBundleEditorWrapper(AbstractRBD theRbdBundle, AbstractEditor ed, - Boolean useRBDName ){ - rbdBundle = theRbdBundle; - ncEditor = ed; - NcEditorUtil.setDisplayAvailable( ed, false ); - replaceEditorNameWithRbdName = useRBDName; - } - - public AbstractRBD getRbdBundle() { - return rbdBundle; - } - - public AbstractEditor getNcEditor() { - return ncEditor; - } - - public Boolean useRbdNameForEditor() { - return replaceEditorNameWithRbdName; - } - } - private final ConcurrentLinkedQueue seldRBDs; - + // when set we will only load the selected Pane private boolean loadSelectedPaneOnly = false; - + public void setLoadSelectedPaneOnly() { - loadSelectedPaneOnly = true; + loadSelectedPaneOnly = true; } - + public void removeAllSeldRBDs() { - seldRBDs.clear(); - } - - public void addDefaultRBD( NcDisplayType dt, AbstractEditor theEditor ) throws VizException { - AbstractRBD rbd = NcMapRBD.getDefaultRBD( NcDisplayType.NMAP_DISPLAY ); - - rbd.resolveLatestCycleTimes(); // shouldn't be needed but just in case - seldRBDs.add( new RbdBundleEditorWrapper( rbd, theEditor, false ) ); + seldRBDs.clear(); } - public void addRBD( AbstractRBD newRBD, AbstractEditor theEditor ) { - - seldRBDs.add( new RbdBundleEditorWrapper( newRBD, theEditor, true ) ); + public void addDefaultRBD(NcDisplayType dt, AbstractEditor theEditor) + throws VizException { + AbstractRBD rbd = NcMapRBD.getDefaultRBD(NcDisplayType.NMAP_DISPLAY); + + rbd.resolveLatestCycleTimes(); // shouldn't be needed but just in case + seldRBDs.add(new RbdBundleEditorWrapper(rbd, theEditor, false)); + } + + public void addRBD(AbstractRBD newRBD, AbstractEditor theEditor) { + + seldRBDs.add(new RbdBundleEditorWrapper(newRBD, theEditor, true)); + } + + public ResourceBndlLoader(String name) { // name of the Job + // super(name); + seldRBDs = new ConcurrentLinkedQueue(); } - public ResourceBndlLoader( String name ) { // name of the Job - //super(name); - seldRBDs = new ConcurrentLinkedQueue(); - } - private class ErrorMsg implements Runnable { - String errMsg=""; - ErrorMsg( String em ) { - errMsg = em; - } - public void run() { - Status status = new Status(Status.ERROR, UiPlugin.PLUGIN_ID, 0, errMsg, null ); - ErrorDialog.openError(Display.getCurrent().getActiveShell(), - "ERROR", errMsg, status); - } - } - - // check that the + String errMsg = ""; + + ErrorMsg(String em) { + errMsg = em; + } + + public void run() { + Status status = new Status(Status.ERROR, UiPlugin.PLUGIN_ID, 0, + errMsg, null); + ErrorDialog.openError(Display.getCurrent().getActiveShell(), + "ERROR", errMsg, status); + } + } + + // check that the public boolean areSeldRBDsGeoSyncCompatible() { - return true; + return true; } - -// @Override -// protected IStatus run(IProgressMonitor monitor) { - //public void loadRBDs() { - public void run() { - RbdBundleEditorWrapper[] wrapperClassArray= ( RbdBundleEditorWrapper[] ) seldRBDs.toArray ( new RbdBundleEditorWrapper[0] ); - - if( loadSelectedPaneOnly ) { - if( wrapperClassArray.length > 1 ) { - System.out.println("Warning: rbdLoader should only load one RBD when"+ - "loadSelectedPaneOnly is true??" ); - } - } - - for ( RbdBundleEditorWrapper thisWrapper : wrapperClassArray ) { - try { - AbstractRBD rbdBndl = thisWrapper.getRbdBundle(); - - // the editor should have already be created with the right - // number of displays and matching paneLayouts - AbstractEditor editor = thisWrapper.getNcEditor(); - - if( editor == null ) { - throw new VizException("??editor is null in rbdLoader?"); - } - - // If this editor currently has resources loaded, clear them out except for PGEN - // - for( int paneIndx=0 ; paneIndx rlist = pane.getRenderableDisplay().getDescriptor().getResourceList(); - if( rlist == null ) { - throw new VizException("The ResourceList is empty?"); - } - Iterator it = rlist.iterator(); - - while( it.hasNext() ){ - ResourcePair rp = it.next(); - if ( !rp.getResource().getClass().getName().endsWith("PgenResource") ) { - rlist.remove(rp); - } - } - } - - NcEditorUtil.setAutoUpdate( editor, rbdBndl.isAutoUpdate() ); - NcEditorUtil.setGeoSyncPanesEnabled( editor, rbdBndl.isGeoSyncedPanes() ); - NcEditorUtil.setHideShow( editor, false); //init to false, means rsc on - - IDisplayPane displayPanes[] = editor.getDisplayPanes(); - IDisplayPane seldPane = null; - INcPaneLayout playout = NcEditorUtil.getPaneLayout( editor ); - - if( loadSelectedPaneOnly ) { - - if( !playout.containsPaneId( rbdBndl.getSelectedPaneId() ) ) { -// playout.getRows() <= rbdBndl.getSelectedPaneId().getRow() || -// playout.getColumns() <= rbdBndl.getSelectedPaneId().getColumn() ) { -// - throw new VizException("Error: The Active Display doesn't have enough Panes"+ - " for the selected Pane: "); - } - } - else if( !playout.equals( rbdBndl.getPaneLayout() ) ) { - throw new VizException("PaneLayouts of the RBD and Editor don't match?"); - } - - // loop thru the panes in the RBD - // - for( int paneIndx=0 ; paneIndx 1) { + System.out + .println("Warning: rbdLoader should only load one RBD when" + + "loadSelectedPaneOnly is true??"); + } + } - // don't load this pane if we are only loading the selected pane and - // this isn't it - if( loadSelectedPaneOnly && - rbdBndl.getSelectedPaneId().compareTo( paneid ) != 0 ) { - continue; - } + for (RbdBundleEditorWrapper thisWrapper : wrapperClassArray) { - IDisplayPane displayPane = NcEditorUtil.getDisplayPane( editor, paneid ); - INatlCntrsRenderableDisplay mapDisp = rbdBndl.getDisplayPane( paneid ); + try { + AbstractRBD rbdBndl = thisWrapper.getRbdBundle(); - if( seldPane == null ) { - seldPane = displayPane; - } + // the editor should have already be created with the right + // number of displays and matching paneLayouts + AbstractEditor editor = thisWrapper.getNcEditor(); - // if the editor was just created and there was an error, close the editor. - // TODO: if there is an error, prompt if the user wishes to continue. - if( loadResourceBundleDefn( displayPane, - mapDisp, rbdBndl.getTimeMatcher() ) == false ) { + if (editor == null) { + throw new VizException("??editor is null in rbdLoader?"); + } - throw new VizException("Error Loading Pane "+paneid.toString()+ - " for RBD "+ rbdBndl.getRbdName() ); - } - } - - // if using the RBD name as the display name, set the tab title - // (this will be the case unless we are loading the default RBD in - // which case the name may be different. ie. NCTEXT, NSHARP or user-defined. - // - if( thisWrapper.useRbdNameForEditor() ) { + // If this editor currently has resources loaded, clear them out + // except for PGEN + // + for (int paneIndx = 0; paneIndx < rbdBndl.getPaneLayout() + .getNumberOfPanes(); paneIndx++) { + NcPaneID paneid = (NcPaneID) rbdBndl.getPaneLayout() + .createPaneId(paneIndx); + IDisplayPane pane = NcEditorUtil.getDisplayPane(editor, + paneid); - NcDisplayName dispName = NcEditorUtil.getDisplayName( editor ); - dispName = new NcDisplayName( dispName.getId(), rbdBndl.getRbdName() ); - NcEditorUtil.setDisplayName( editor, dispName); - - editor.setTabTitle( dispName.toString() ); - } - - editor.refresh(); - NcEditorUtil.refreshGUIElements( editor ); - // flag the editor as 'loaded' so that it is no longer considered 'empty' or available - NcEditorUtil.setDisplayAvailable( editor, rbdBndl.getIsDefaultRbd() ); + if (pane == null) { + throw new VizException("Could not get pane " + + paneid.toString() + " from the editor."); + } - NcDisplayMngr.bringToTop( editor ); - } - catch ( VizException vizex ) { - VizApp.runAsync( - new ErrorMsg( vizex.getMessage() ) ); - } - } - - removeAllSeldRBDs(); - - // this.cancel(); if a Job - // return null; + // don't clear this pane if we are only loading the selected + // pane and + // this isn't it + if (loadSelectedPaneOnly + && rbdBndl.getSelectedPaneId().compareTo(paneid) != 0) { + continue; + } + + List rlist = pane.getRenderableDisplay() + .getDescriptor().getResourceList(); + if (rlist == null) { + throw new VizException("The ResourceList is empty?"); + } + Iterator it = rlist.iterator(); + + while (it.hasNext()) { + ResourcePair rp = it.next(); + if (rp.getResource() != null) { + if (!rp.getResource().getClass().getName() + .endsWith("PgenResource")) { + rlist.remove(rp); + } + } + } + } + + NcEditorUtil.setAutoUpdate(editor, rbdBndl.isAutoUpdate()); + NcEditorUtil.setGeoSyncPanesEnabled(editor, + rbdBndl.isGeoSyncedPanes()); + NcEditorUtil.setHideShow(editor, false); // init to false, means + // rsc on + + IDisplayPane displayPanes[] = editor.getDisplayPanes(); + IDisplayPane seldPane = null; + INcPaneLayout playout = NcEditorUtil.getPaneLayout(editor); + + if (loadSelectedPaneOnly) { + + if (!playout.containsPaneId(rbdBndl.getSelectedPaneId())) { + // playout.getRows() <= + // rbdBndl.getSelectedPaneId().getRow() || + // playout.getColumns() <= + // rbdBndl.getSelectedPaneId().getColumn() ) { + // + throw new VizException( + "Error: The Active Display doesn't have enough Panes" + + " for the selected Pane: "); + } + } else if (!playout.equals(rbdBndl.getPaneLayout())) { + throw new VizException( + "PaneLayouts of the RBD and Editor don't match?"); + } + + // loop thru the panes in the RBD + // + for (int paneIndx = 0; paneIndx < rbdBndl.getPaneLayout() + .getNumberOfPanes(); paneIndx++) { + NcPaneID paneid = (NcPaneID) rbdBndl.getPaneLayout() + .createPaneId(paneIndx); + + // don't load this pane if we are only loading the selected + // pane and + // this isn't it + if (loadSelectedPaneOnly + && rbdBndl.getSelectedPaneId().compareTo(paneid) != 0) { + continue; + } + + IDisplayPane displayPane = NcEditorUtil.getDisplayPane( + editor, paneid); + INatlCntrsRenderableDisplay mapDisp = rbdBndl + .getDisplayPane(paneid); + + if (seldPane == null) { + seldPane = displayPane; + } + + // if the editor was just created and there was an error, + // close the editor. + // TODO: if there is an error, prompt if the user wishes to + // continue. + if (loadResourceBundleDefn(displayPane, mapDisp, + rbdBndl.getTimeMatcher()) == false) { + + throw new VizException("Error Loading Pane " + + paneid.toString() + " for RBD " + + rbdBndl.getRbdName()); + } + } + + // if using the RBD name as the display name, set the tab title + // (this will be the case unless we are loading the default RBD + // in + // which case the name may be different. ie. NCTEXT, NSHARP or + // user-defined. + // + if (thisWrapper.useRbdNameForEditor()) { + + NcDisplayName dispName = NcEditorUtil + .getDisplayName(editor); + dispName = new NcDisplayName(dispName.getId(), + rbdBndl.getRbdName()); + NcEditorUtil.setDisplayName(editor, dispName); + + editor.setTabTitle(dispName.toString()); + } + + editor.refresh(); + NcEditorUtil.refreshGUIElements(editor); + // flag the editor as 'loaded' so that it is no longer + // considered 'empty' or available + NcEditorUtil.setDisplayAvailable(editor, + rbdBndl.getIsDefaultRbd()); + + NcDisplayMngr.bringToTop(editor); + } catch (VizException vizex) { + VizApp.runAsync(new ErrorMsg(vizex.getMessage())); + } + } + + removeAllSeldRBDs(); + + // this.cancel(); if a Job + // return null; } - + // // - public boolean loadResourceBundleDefn( IDisplayPane pane, - INatlCntrsRenderableDisplay mapDisplay, NCTimeMatcher timeMatcher ) { + public boolean loadResourceBundleDefn(IDisplayPane pane, + INatlCntrsRenderableDisplay mapDisplay, NCTimeMatcher timeMatcher) { - if( timeMatcher == null ) { - System.out.println("Error Loading Timeline???"); - return false; - } - - INatlCntrsDescriptor descr = (INatlCntrsDescriptor) mapDisplay.getDescriptor(); + if (timeMatcher == null) { + System.out.println("Error Loading Timeline???"); + return false; + } - descr.setTimeMatcher( timeMatcher ); - descr.setNumberOfFrames( timeMatcher.getNumFrames() ); - DataTime[] dataTimes = timeMatcher.getFrameTimes().toArray( new DataTime[0] ); + INatlCntrsDescriptor descr = (INatlCntrsDescriptor) mapDisplay + .getDescriptor(); - if( dataTimes == null || - dataTimes.length == 0 ) { - // descr.setDataTimes( null ); - } - else { - descr.setDataTimes( dataTimes ); - - if( timeMatcher.isForecast() ) { - descr.setFrame( 0 ); - } - else { - descr.setFrame( dataTimes.length-1 ); - } - } + descr.setTimeMatcher(timeMatcher); + descr.setNumberOfFrames(timeMatcher.getNumFrames()); + DataTime[] dataTimes = timeMatcher.getFrameTimes().toArray( + new DataTime[0]); - ResourceList rscList = descr.getResourceList(); + if (dataTimes == null || dataTimes.length == 0) { + // descr.setDataTimes( null ); + } else { + descr.setDataTimes(dataTimes); - // Add PGEN resource back - if ( !pane.getRenderableDisplay().getDescriptor().getResourceList().isEmpty() ){ - rscList.addAll( pane.getRenderableDisplay().getDescriptor().getResourceList()); - } + if (timeMatcher.isForecast()) { + descr.setFrame(0); + } else { + descr.setFrame(dataTimes.length - 1); + } + } - rscList.instantiateResources( descr, true ); - - // TODO : change the resource-capable (ie Satellite) resourceData objects to be able - // to query for the gridCoverage before the resource object is created. We should - // be able to query the mcidas_area_names/mcidas_spatial tables knowing just the info - // in the resourceData object. - // But until then resourceData objects just return dummy coverages and - // we will need to reproject the mapDisplay after the resource is loaded - // if the area is to be set from a resource-defined area, we need - // - pane.setRenderableDisplay( mapDisplay ); - - PredefinedArea initArea = mapDisplay.getInitialArea(); + ResourceList rscList = descr.getResourceList(); - if( initArea.getSource() != AreaSource.PREDEFINED_AREA ) { + // Add PGEN resource back + if (!pane.getRenderableDisplay().getDescriptor().getResourceList() + .isEmpty()) { + rscList.addAll(pane.getRenderableDisplay().getDescriptor() + .getResourceList()); + } - if( initArea.getZoomLevel().equals( ZoomLevelStrings.SizeOfImage.toString() ) ) { - Rectangle rect = pane.getBounds(); -// mapDisplay.setExtent( new PixelExtent( rect ) ); - mapDisplay.setExtent( new PixelExtent( - rect.x, rect.x + rect.width, - rect.y, rect.y + rect.height ) ); - ((NCMapDescriptor)descr).setSuspendZoom( true ); -// ZoomUtil.suspendZoom( mapDisplay.getContainer() ) ; - } - else if( initArea.getZoomLevel().equals( ZoomLevelStrings.FitToScreen.toString() ) ) { + rscList.instantiateResources(descr, true); - } - } - - pane.setZoomLevel( mapDisplay.getZoomLevel() ); - pane.refresh(); + // TODO : change the resource-capable (ie Satellite) resourceData + // objects to be able + // to query for the gridCoverage before the resource object is created. + // We should + // be able to query the mcidas_area_names/mcidas_spatial tables knowing + // just the info + // in the resourceData object. + // But until then resourceData objects just return dummy coverages and + // we will need to reproject the mapDisplay after the resource is loaded + // if the area is to be set from a resource-defined area, we need + // + pane.setRenderableDisplay(mapDisplay); - return true; - } + PredefinedArea initArea = mapDisplay.getInitialArea(); + + if (initArea.getSource() != AreaSource.PREDEFINED_AREA) { + + if (initArea.getZoomLevel().equals( + ZoomLevelStrings.SizeOfImage.toString())) { + Rectangle rect = pane.getBounds(); + // mapDisplay.setExtent( new PixelExtent( rect ) ); + mapDisplay.setExtent(new PixelExtent(rect.x, rect.x + + rect.width, rect.y, rect.y + rect.height)); + ((NCMapDescriptor) descr).setSuspendZoom(true); + // ZoomUtil.suspendZoom( mapDisplay.getContainer() ) ; + } else if (initArea.getZoomLevel().equals( + ZoomLevelStrings.FitToScreen.toString())) { + + } + } + + pane.setZoomLevel(mapDisplay.getZoomLevel()); + pane.refresh(); + + return true; + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java index d8e467119f..eef52d1983 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceCategory.java @@ -18,101 +18,122 @@ import javax.xml.bind.annotation.adapters.XmlAdapter; * ------------ ---------- ----------- -------------------------- * 02/13/13 #972 Greg Hull Created * 03/06/13 #958 Greg Hull Added SpaceRscCategory - * + * 05/15/2014 #1131 Quan Zhou Added resource category GraphRscCategory. * * - * @author + * @author * @version 1 */ @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) public class ResourceCategory implements Comparable { - - public static class ResourceCategoryAdapter extends XmlAdapter { - // - @Override - public ResourceCategory unmarshal(String n) throws Exception { - if( ResourceCategory.getCategory( n ) == ResourceCategory.NullCategory ) { - ResourceCategory.createCategory( n ); - } - return ResourceCategory.getCategory( n ); - } - @Override - public String marshal(ResourceCategory rc) throws Exception { - return rc.toString(); - } - } - + public static class ResourceCategoryAdapter extends + XmlAdapter { + // + @Override + public ResourceCategory unmarshal(String n) throws Exception { + if (ResourceCategory.getCategory(n) == ResourceCategory.NullCategory) { + ResourceCategory.createCategory(n); + } + return ResourceCategory.getCategory(n); + } + + @Override + public String marshal(ResourceCategory rc) throws Exception { + return rc.toString(); + } + } + private static Map catMap = new HashMap(); - public static ResourceCategory SatelliteRscCategory = createCategory( "SATELLITE", 100 ); - public static ResourceCategory RadarRscCategory = createCategory( "RADAR", 200 ); - public static ResourceCategory GridRscCategory = createCategory( "GRID", 300 ); - public static ResourceCategory SurfaceRscCategory = createCategory( "SURFACE", 400 ); - public static ResourceCategory UpperAirRscCategory = createCategory( "UPPER_AIR", 500 ); - public static ResourceCategory PGENRscCategory = createCategory( "PGEN", 600 ); - public static ResourceCategory MiscRscCategory = createCategory( "MISC", 700 ); - public static ResourceCategory EnsembleRscCategory = createCategory( "ENSEMBLE", 800 ); - public static ResourceCategory OverlayRscCategory = createCategory( "OVERLAY", 900 ); - public static ResourceCategory SpaceRscCategory = createCategory( "SOLARIMAGE", 850 ); - - private static int nextCatOrder = OverlayRscCategory.order+100; - - public static ResourceCategory NullCategory = new ResourceCategory( "NULL", -1 ); - - // NOTE : These are available if the users don't like the SURFACE/UPPER_AIR - // categories as configured in the resourceDefinitions file. - // -// SurfaceFcstRscCategory = "SURF_FCST"; -// UpperAirFcstRscCategory = "UAIR_FCST"; -// SurfaceObsRscCategory = "SURF_OBS"; -// UpperAirObsRscCategory = "UAIR_OBS"; - // IMAGE, MODEL, WATCH/WARNING + public static ResourceCategory SatelliteRscCategory = createCategory( + "SATELLITE", 100); - private String catName; - private int order; - + public static ResourceCategory RadarRscCategory = createCategory("RADAR", + 200); - private ResourceCategory( String name, int ord ) { - catName = name; - order = ord; - } - - public static ResourceCategory getCategory( String name ) { - ResourceCategory rc = catMap.get( name.trim().toUpperCase() ); - return (rc == null ? ResourceCategory.NullCategory : rc ); - } - - public static ResourceCategory createCategory( String name ) { - return createCategory( name, nextCatOrder++ ); - } - - public static ResourceCategory createCategory( String name, int ord ) { + public static ResourceCategory GridRscCategory = createCategory("GRID", 300); + + public static ResourceCategory SurfaceRscCategory = createCategory( + "SURFACE", 400); + + public static ResourceCategory UpperAirRscCategory = createCategory( + "UPPER_AIR", 500); + + public static ResourceCategory PGENRscCategory = createCategory("PGEN", 600); + + public static ResourceCategory MiscRscCategory = createCategory("MISC", 700); + + public static ResourceCategory EnsembleRscCategory = createCategory( + "ENSEMBLE", 800); + + public static ResourceCategory OverlayRscCategory = createCategory( + "OVERLAY", 900); + + public static ResourceCategory SpaceRscCategory = createCategory( + "SOLARIMAGE", 850); + + public static ResourceCategory GraphRscCategory = createCategory( + "TIMESERIES", 860); + + private static int nextCatOrder = OverlayRscCategory.order + 100; + + public static ResourceCategory NullCategory = new ResourceCategory("NULL", + -1); + + // NOTE : These are available if the users don't like the SURFACE/UPPER_AIR + // categories as configured in the resourceDefinitions file. + // + // SurfaceFcstRscCategory = "SURF_FCST"; + // UpperAirFcstRscCategory = "UAIR_FCST"; + // SurfaceObsRscCategory = "SURF_OBS"; + // UpperAirObsRscCategory = "UAIR_OBS"; + // IMAGE, MODEL, WATCH/WARNING + + private String catName; + + private int order; + + private ResourceCategory(String name, int ord) { + catName = name; + order = ord; + } + + public static ResourceCategory getCategory(String name) { + ResourceCategory rc = catMap.get(name.trim().toUpperCase()); + return (rc == null ? ResourceCategory.NullCategory : rc); + } + + public static ResourceCategory createCategory(String name) { + return createCategory(name, nextCatOrder++); + } + + public static ResourceCategory createCategory(String name, int ord) { name = String.valueOf(name).toUpperCase().trim(); - ResourceCategory rCat = catMap.get( name ); - - if( rCat == null ) { - rCat = new ResourceCategory( name, ord ); - catMap.put( name, rCat ); + ResourceCategory rCat = catMap.get(name); + + if (rCat == null) { + rCat = new ResourceCategory(name, ord); + catMap.put(name, rCat); } return rCat; - } - - public String getCategoryName() { - return catName; - } - - public Boolean isPgenCategory() { - return this == PGENRscCategory; - } + } - public String toString() { - return catName; - } - - public static ResourceCategory[] values() { - ResourceCategory[] cats = catMap.values().toArray( + public String getCategoryName() { + return catName; + } + + public Boolean isPgenCategory() { + return this == PGENRscCategory; + } + + public String toString() { + return catName; + } + + public static ResourceCategory[] values() { + ResourceCategory[] cats = catMap.values().toArray( new ResourceCategory[catMap.size()]); Arrays.sort(cats); return cats; @@ -140,8 +161,8 @@ public class ResourceCategory implements Comparable { return true; } - @Override - public int compareTo(ResourceCategory c) { - return order - c.order; - } + @Override + public int compareTo(ResourceCategory c) { + return order - c.order; + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java index cef4c76c38..5b64fc4aea 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefinition.java @@ -1,6 +1,7 @@ package gov.noaa.nws.ncep.viz.resources.manager; import static java.lang.System.out; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; import gov.noaa.nws.ncep.common.dataplugin.mcidas.McidasRecord; import gov.noaa.nws.ncep.common.dataplugin.ntrans.NtransRecord; import gov.noaa.nws.ncep.common.dataplugin.pgen.PgenRecord; @@ -83,9 +84,9 @@ import com.raytheon.viz.alerts.observers.ProductAlertObserver; * 04/2013 #838 B. Hebbard Add special handling (like satellite) for NTRANS compound subType * 08/2013 #1031 Greg Hull modified inventory query * 11/2013 #1074 Greg Hull fix bug generating native satellite sub-type + * 05/15/2014 #1131 Quan Zhou Added resource category GraphRscCategory. Added dfltGraphRange, dfltHourSnap * 06/2014 B. Hebbard Force getInventoryEnabled() to return false except for GRID & ENSEMBLE * resources, and make all internal read accesses via getter - * * * * @author ghull @@ -126,6 +127,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // the resource types generated by rscTypeGenerator from either the // NcInventory or, if the inventory is disabled, the DB. + private ArrayList generatedTypesList; private ArrayList generatedSubTypesList; @@ -141,6 +143,10 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, private static final int DEFAULT_FRAME_COUNT = 10; + private static final int DEFAULT_GRAPH_RANGE = 12; // in hours quan + + private static final int DEFAULT_HOUR_SNAP = 3; + private static final int DEFAULT_TIME_RANGE = 24; // in hours @XmlElement @@ -150,6 +156,15 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, @XmlElement private int dfltTimeRange; + // the hours range in graph display. + @XmlElement + private int dfltGraphRange; + + // the default hour selection snap number. For example, 3 means hours must + // be select in 0,3,6,9... + @XmlElement + private int dfltHourSnap; + // where/how are the attribute sets located/organized // public static enum AttrSetsOrganization { @@ -174,6 +189,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // the user edits the params in the GUI. This are not returned by // getResourceParameters but it would be nice to have a cleaner way to // store the comments for a parameter. + @XmlElement @XmlJavaTypeAdapter(RscParamsJaxBAdapter.class) private HashMap resourceParameters; @@ -184,6 +200,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // implementations // Default to disabled so it must be explicitly enabled. + @XmlElement private Boolean inventoryEnabled = false; @@ -207,6 +224,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // This is currently only used for the latestTimes in the attr set list. // The actual times are still coming from the NcInventory or the DB. // + @XmlElement private Boolean addToURICatalog = false; @@ -221,6 +239,8 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, frameSpan = 0; dfltFrameCount = DEFAULT_FRAME_COUNT; dfltTimeRange = DEFAULT_TIME_RANGE; + dfltGraphRange = DEFAULT_GRAPH_RANGE; + dfltHourSnap = DEFAULT_HOUR_SNAP; dfltGeogArea = ""; timeMatchMethod = TimeMatchMethod.CLOSEST_BEFORE_OR_AFTER; timelineGenMethod = timelineGenMethod.USE_DATA_TIMES; @@ -250,7 +270,8 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, frameSpan = rscDefn.frameSpan; dfltFrameCount = rscDefn.dfltFrameCount; dfltTimeRange = rscDefn.dfltTimeRange; - + dfltGraphRange = rscDefn.dfltGraphRange; + dfltHourSnap = rscDefn.dfltHourSnap; timeMatchMethod = rscDefn.timeMatchMethod; timelineGenMethod = rscDefn.timelineGenMethod; @@ -314,6 +335,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // TODO : Need to change this to return the constraint field instead of // the generator parameter. Til then all parameters that generate a type // or sub type must be the same name as the request constraint. + public String getRscTypeGenerator() { return (rscTypeGenerator == null ? "" : rscTypeGenerator); } @@ -482,8 +504,7 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, public boolean isForecast() { // @formatter:off - return (timelineGenMethod == TimelineGenMethod.USE_CYCLE_TIME_FCST_HOURS || - timelineGenMethod == TimelineGenMethod.USE_FCST_FRAME_INTERVAL_FROM_REF_TIME); + return (timelineGenMethod == TimelineGenMethod.USE_CYCLE_TIME_FCST_HOURS || timelineGenMethod == TimelineGenMethod.USE_FCST_FRAME_INTERVAL_FROM_REF_TIME); // @formatter:on // return filterLabels.contains("Forecast"); } @@ -540,6 +561,22 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, this.dfltFrameCount = dfltFrameCount; } + public int getDfltGraphRange() { + return dfltGraphRange; + } + + public void setDfltGraphRange(int dfltGraphRange) { + this.dfltGraphRange = dfltGraphRange; + } + + public int getDfltHourSnap() { + return dfltHourSnap; + } + + public void setDfltHourSnap(int dfltHourSnap) { + this.dfltHourSnap = dfltHourSnap; + } + public int getDfltTimeRange() { return dfltTimeRange; } @@ -573,14 +610,14 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, } public boolean applyAttrSetGroups() { + if (attrSetOrg == AttrSetsOrganization.DETERMINE_BY_RSC_CATEGORY) { - // @formatter:off - return resourceCategory == ResourceCategory.GridRscCategory || - resourceCategory == ResourceCategory.RadarRscCategory || - // resourceCategory == ResourceCategory.PGENRscCategory || - resourceCategory == ResourceCategory.EnsembleRscCategory || - resourceCategory == ResourceCategory.SpaceRscCategory; - // @formatter:on + return resourceCategory == ResourceCategory.GridRscCategory + || resourceCategory == ResourceCategory.RadarRscCategory + || resourceCategory == ResourceCategory.GraphRscCategory + // resourceCategory == ResourceCategory.PGENRscCategory || + || resourceCategory == ResourceCategory.EnsembleRscCategory + || resourceCategory == ResourceCategory.SpaceRscCategory; } else if (attrSetOrg == AttrSetsOrganization.BY_ATTR_SET_GROUP) { return true; } else { @@ -660,11 +697,11 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // else { // 'LIKE' doesn't work for integers. Just leave this out. // if (prmInfo.getParamClass() == Integer.class) { - // inventoryConstraints.put (cnstrName, - // RequestConstraint.WILDCARD); + // inventoryConstraints.put (cnstrName, + // RequestConstraint.WILDCARD); // } // inventoryConstraints.put (cnstrName, - // RequestConstraint.WILDCARD); + // RequestConstraint.WILDCARD); // } // @formatter:on } @@ -707,9 +744,9 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, public Boolean getInventoryEnabled() { // @formatter:off return inventoryEnabled && - // force to false (disabled) for non-grid non-ensemble resources - (resourceCategory.equals(ResourceCategory.GridRscCategory) || - resourceCategory.equals(ResourceCategory.EnsembleRscCategory)); + // force to false (disabled) for non-grid non-ensemble resources + (resourceCategory.equals(ResourceCategory.GridRscCategory) || resourceCategory + .equals(ResourceCategory.EnsembleRscCategory)); // @formatter:on } @@ -1056,24 +1093,24 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, // private void initInventory (Boolean reload) throws VizException { // // if (!usesInventory()) { - // return; + // return; // } // else if (getPluginName() == null) { - // throw new VizException ("Error creating ResourceDefn (" + - // resourceDefnName + - // ") The pluginName must be given as a resource parameter." ); + // throw new VizException ("Error creating ResourceDefn (" + + // resourceDefnName + + // ") The pluginName must be given as a resource parameter." ); // } // else if (getPluginName().equals(GempakGrid.gempakPluginName)) { - // return; + // return; // } // else if (isInventoryInitialized() && !reload) { - // return; + // return; // } // else if (!isInventoryInitialized() && reload) { // // can't reload if not created yet // //reload = // } - // return; + // return; // } // @formatter:on @@ -1790,6 +1827,9 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, .println("Unrecognized PGEN rsc generating subType" + subTypeGenerator); } + } else if (getResourceCategory() == ResourceCategory.GraphRscCategory) { + GeoMagRecord magRec = (GeoMagRecord) pdo; + subType = magRec.getStationCode(); } // doing this will cause the dataTime query to fail because @@ -1984,6 +2024,10 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, return false; if (dfltTimeRange != other.dfltTimeRange) return false; + if (dfltGraphRange != other.dfltGraphRange) + return false; + if (dfltHourSnap != other.dfltHourSnap) + return false; if (frameSpan != other.frameSpan) return false; if (inventoryEnabled == null) { @@ -2028,4 +2072,4 @@ public class ResourceDefinition implements ISerializableObject, IAlertObserver, return false; return true; } -} \ No newline at end of file +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefnsMngr.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefnsMngr.java index d9f55beef0..ec5c3e05c1 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefnsMngr.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/ResourceDefnsMngr.java @@ -4,7 +4,6 @@ import static java.lang.System.out; import gov.noaa.nws.ncep.edex.common.ncinventory.NcInventoryDefinition; import gov.noaa.nws.ncep.edex.common.ncinventory.NcInventoryRequestMsg; import gov.noaa.nws.ncep.viz.common.SelectableFrameTimeMatcher; -import gov.noaa.nws.ncep.viz.common.dbQuery.NcConnector; import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; import gov.noaa.nws.ncep.viz.localization.NcPathManager; import gov.noaa.nws.ncep.viz.localization.NcPathManager.NcPathConstants; @@ -24,17 +23,10 @@ import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.TreeMap; -import javax.xml.bind.JAXBException; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.geotools.referencing.operation.transform.WarpTransform2D; - import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.localization.FileUpdatedMessage; import com.raytheon.uf.common.localization.FileUpdatedMessage.FileChangeType; @@ -47,10 +39,10 @@ import com.raytheon.uf.common.localization.exception.LocalizationException; import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.serialization.SerializationUtil; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.RecordFactory; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.requests.ThriftClient; + /** * * @@ -95,2403 +87,2653 @@ import com.raytheon.uf.viz.core.requests.ThriftClient; * 06/05/13 #998 Greg Hull init subTypesList when creating new RD. * 08/2013 #1031 Greg Hull retry on inventory directory request * 12/4/13 #1074 Greg Hull another hack for the rscName<->parameterValues mapping; check for - * 'native' in satellite subType and set to 0 resolution. - * + * 'native' in satellite subType and set to 0 resolution. + * 05/15/2014 #1131 Quan Zhou added rparameters dfltGraphRange, dfltHourSnap * * * @author ghull * @version 1 */ public class ResourceDefnsMngr { - - // one instance per user. (Currently only the 'base' used) - // - private static Map instanceMap = - new HashMap(); + + // one instance per user. (Currently only the 'base' used) + // + private static Map instanceMap = new HashMap(); // TODO : fold this into NcPathMngr private NcPathManager pathMngr; - - private HashMap resourceDefnsMap = null; - - // a map from either the rscType or the rscImpl (depending on if AttrSetGroups apply) - // to a list of available Attribute Set Files returned from Localization. - private Map> attrSetMap; - - // map from the rscType+groupName to the AttrSetGroup that - // holds the list of attrSets - private Map attrSetGroupsMap; - - // for parameters which reference a file under localization. - // (ie. ColorBars and PlotModels and the plot model conditional filters) - // NOTE that Conditional Filters dir is under the Plot Models so - // this is not strictly necessary. - private static final String[] refdParamDirectories = { - NcPathConstants.PLOT_MODELS_DIR, - NcPathConstants.CONDITIONAL_FILTERS_DIR, - NcPathConstants.COLORBARS_DIR - }; - - private static Map refdParamFilesMap; - - public static final HashMap paramInfoForRscDefnParamsMap = new HashMap(); - { - paramInfoForRscDefnParamsMap.put("frameSpan", "Integer" ); - paramInfoForRscDefnParamsMap.put("timeMatchMethod", "TimeMatchMethod" ); - paramInfoForRscDefnParamsMap.put("dfltNumFrames", "Integer"); - paramInfoForRscDefnParamsMap.put("dfltTimeRange", "Integer" ); - paramInfoForRscDefnParamsMap.put("timelineGenMethod", "TimelineGenMethod" ); - paramInfoForRscDefnParamsMap.put("isForecast", "Boolean" ); - } - private static List availResourceCategoriesList = - Arrays.asList( ResourceCategory.values() ); - //Arrays.asList( AvailResourceCategories ); + private HashMap resourceDefnsMap = null; - private static String ATTR_SET_FILE_EXT = ".attr"; + // a map from either the rscType or the rscImpl (depending on if + // AttrSetGroups apply) + // to a list of available Attribute Set Files returned from Localization. + private Map> attrSetMap; - private static ResourceDefinition locatorRscDefn = null; - - private static List badRscDefnsList = new ArrayList(); - - private static List rscDefnsWarningsList = new ArrayList(); - - private static Map> rscFiltersMap = null; - - public static synchronized ResourceDefnsMngr getInstance() throws VizException { - return getInstance("base"); - } + // map from the rscType+groupName to the AttrSetGroup that + // holds the list of attrSets + private Map attrSetGroupsMap; - public static synchronized ResourceDefnsMngr getInstance(String user) throws VizException { - ResourceDefnsMngr instance = instanceMap.get(user); - - if( instance == null ) { - try { - instance = new ResourceDefnsMngr(user); - instance.readResourceDefns(); - } catch( VizException ve ) { - throw ve; - } + // for parameters which reference a file under localization. + // (ie. ColorBars and PlotModels and the plot model conditional filters) + // NOTE that Conditional Filters dir is under the Plot Models so + // this is not strictly necessary. + private static final String[] refdParamDirectories = { + NcPathConstants.PLOT_MODELS_DIR, + NcPathConstants.CONDITIONAL_FILTERS_DIR, + NcPathConstants.COLORBARS_DIR }; + + private static Map refdParamFilesMap; + + public static final HashMap paramInfoForRscDefnParamsMap = new HashMap(); + { + paramInfoForRscDefnParamsMap.put("frameSpan", "Integer"); + paramInfoForRscDefnParamsMap.put("timeMatchMethod", "TimeMatchMethod"); + paramInfoForRscDefnParamsMap.put("dfltNumFrames", "Integer"); + paramInfoForRscDefnParamsMap.put("dfltGraphRange", "Integer"); + paramInfoForRscDefnParamsMap.put("dfltHourSnap", "Integer"); + paramInfoForRscDefnParamsMap.put("dfltTimeRange", "Integer"); + paramInfoForRscDefnParamsMap.put("timelineGenMethod", + "TimelineGenMethod"); + paramInfoForRscDefnParamsMap.put("isForecast", "Boolean"); + } + + private static List availResourceCategoriesList = Arrays + .asList(ResourceCategory.values()); + + // Arrays.asList( AvailResourceCategories ); + + private static String ATTR_SET_FILE_EXT = ".attr"; + + private static ResourceDefinition locatorRscDefn = null; + + private static List badRscDefnsList = new ArrayList(); + + private static List rscDefnsWarningsList = new ArrayList(); + + private static Map> rscFiltersMap = null; + + public static synchronized ResourceDefnsMngr getInstance() + throws VizException { + return getInstance("base"); + } + + public static synchronized ResourceDefnsMngr getInstance(String user) + throws VizException { + ResourceDefnsMngr instance = instanceMap.get(user); + + if (instance == null) { + try { + instance = new ResourceDefnsMngr(user); + instance.readResourceDefns(); + } catch (VizException ve) { + throw ve; + } instanceMap.put(user, instance); } - //instance.initializeInventory(); - + // instance.initializeInventory(); + return instance; - } - - private ResourceDefnsMngr( String user ) { - - // check for an environment variable to override the inventory strategies. - // -// String inventoryLoadStrategy = System.getenv().get("INVENTORY_STRATEGY"); -// out.println("INVENTORY_STRATEGY is " + (inventoryLoadStrategy != null ? inventoryLoadStrategy : " Not set ") ); - - pathMngr = NcPathManager.getInstance(); -// searchContexts = pathMngr.getLocalSearchHierarchy( LocalizationType.CAVE_STATIC ); - } - - public List getBadResourceDefnsErrors() { - return badRscDefnsList; - } + } - public List getResourceDefnWarnings() { - return rscDefnsWarningsList; - } - - public List getAllResourceDefinitions() { - return new ArrayList( resourceDefnsMap.values() ); - } - - // The RDs should already have been read in. - // fill in the rscFiltersmap from all localization files (all levels that is.) - // if no file is present, enable everything. - // - private void readResourceFilters() throws VizException { + private ResourceDefnsMngr(String user) { - if( rscFiltersMap == null ) { - rscFiltersMap = new HashMap>(); - - // If a RD is not found in a Filters file then it will be enabled by default. - // - Boolean dfltEnableState = true; + // check for an environment variable to override the inventory + // strategies. + // + // String inventoryLoadStrategy = + // System.getenv().get("INVENTORY_STRATEGY"); + // out.println("INVENTORY_STRATEGY is " + (inventoryLoadStrategy != null + // ? inventoryLoadStrategy : " Not set ") ); - // get all versions of the file and parse each one. - Map filtFiles = pathMngr.getTieredLocalizationFile( NcPathConstants.RESOURCE_FILTERS ); + pathMngr = NcPathManager.getInstance(); + // searchContexts = pathMngr.getLocalSearchHierarchy( + // LocalizationType.CAVE_STATIC ); + } - // if there is no filter files then display a warning and continue - if( filtFiles == null ) { - dfltEnableState = true; - rscDefnsWarningsList.add( - new VizException( "Could not find any "+ - NcPathConstants.RESOURCE_FILTERS + " files. \n"+ - "All Rsc Defns will be enabled w/o any filters" ) ); - } + public List getBadResourceDefnsErrors() { + return badRscDefnsList; + } - for( LocalizationLevel locLvl : filtFiles.keySet() ) { - - LocalizationFile rscFiltersLFile = filtFiles.get( locLvl ); - - rscFiltersLFile.addFileUpdatedObserver( new ILocalizationFileObserver() { - @Override - public void fileUpdated(FileUpdatedMessage msg) { -// System.out.println("Localization File updated: " + -// msg.getFileName()+" "+msg.getChangeType().toString() ); + public List getResourceDefnWarnings() { + return rscDefnsWarningsList; + } - // if deleting or updating then - // remove all of the entries in the map at this localization lvl - // - if( msg.getChangeType() == FileChangeType.DELETED || - msg.getChangeType() == FileChangeType.UPDATED ) { - - for( String rdName : rscFiltersMap.keySet() ) { - TreeMap filtMap = - rscFiltersMap.get( rdName ); - filtMap.remove( msg.getContext().getLocalizationLevel() ); - } - } + public List getAllResourceDefinitions() { + return new ArrayList(resourceDefnsMap.values()); + } - // if adding or updating, reread the file. - if( msg.getChangeType() == FileChangeType.ADDED || - msg.getChangeType() == FileChangeType.UPDATED ) { - - try { - LocalizationFile locFile = - NcPathManager.getInstance().getLocalizationFile( - msg.getContext(), msg.getFileName() ); + // The RDs should already have been read in. + // fill in the rscFiltersmap from all localization files (all levels that + // is.) + // if no file is present, enable everything. + // + private void readResourceFilters() throws VizException { - readRscFilter( locFile ); - - } catch (SerializationException e) { - } - } - } - }); - - - try { - readRscFilter( rscFiltersLFile ); - } - catch (SerializationException e) { - rscDefnsWarningsList.add( new VizException(e) ); - System.out.println("error serializing"+rscFiltersLFile.getFile().getAbsolutePath()+ - " : "+e.getMessage() ); - } - } + if (rscFiltersMap == null) { + rscFiltersMap = new HashMap>(); - // loop thru all the RDs and if there is no entry in the filters map, add one - // at the same level as the RD. - // - for( ResourceDefinition rd : resourceDefnsMap.values() ) { - String rdName = rd.getResourceDefnName(); - - TreeMap filterTreeMap = - rscFiltersMap.get( rdName ); + // If a RD is not found in a Filters file then it will be enabled by + // default. + // + Boolean dfltEnableState = true; - if( filterTreeMap == null ) { - filterTreeMap = new TreeMap( - LocalizationLevel.REVERSE_COMPARATOR ); - filterTreeMap.put( rd.getLocalizationFile().getContext().getLocalizationLevel(), - new ResourceDefinitionFilter( rdName, dfltEnableState, null, - rd.getLocalizationFile().getContext().getLocalizationLevel() ) ); - rscFiltersMap.put( rdName, filterTreeMap ); + // get all versions of the file and parse each one. + Map filtFiles = pathMngr + .getTieredLocalizationFile(NcPathConstants.RESOURCE_FILTERS); - // if there a filters file then this one is just missing for some reason. - if( filtFiles != null ) { - rscDefnsWarningsList.add( - new VizException( "Could not find the Rsc Defn,"+rdName+", in any ResourceDefintionFilters files."+ - " it will be Enabled by default.") ); - } - } - } - } + // if there is no filter files then display a warning and continue + if (filtFiles == null) { + dfltEnableState = true; + rscDefnsWarningsList.add(new VizException("Could not find any " + + NcPathConstants.RESOURCE_FILTERS + " files. \n" + + "All Rsc Defns will be enabled w/o any filters")); + } - return; - } - - private void readRscFilter( LocalizationFile locFile ) throws SerializationException { - String fileName = locFile.getFile().getAbsolutePath(); - LocalizationLevel lLvl = locFile.getContext().getLocalizationLevel(); - - synchronized ( rscFiltersMap ) { - ResourceDefinitionFilters rscDfnFilters = SerializationUtil.jaxbUnmarshalFromXmlFile( - ResourceDefinitionFilters.class, fileName ); + for (LocalizationLevel locLvl : filtFiles.keySet()) { - for( ResourceDefinitionFilter rFilt : rscDfnFilters.getResourceDefinitionFiltersList() ) { - String rdName = rFilt.getRscDefnName(); - rFilt.setLocLevel( lLvl ); + LocalizationFile rscFiltersLFile = filtFiles.get(locLvl); - TreeMap filterTreeMap = - rscFiltersMap.get( rdName ); + rscFiltersLFile + .addFileUpdatedObserver(new ILocalizationFileObserver() { + @Override + public void fileUpdated(FileUpdatedMessage msg) { + // System.out.println("Localization File updated: " + // + + // msg.getFileName()+" "+msg.getChangeType().toString() + // ); - // if there is already an entry in the map, add this one to th - if( filterTreeMap == null ) { - // store entries in reverse order since we only want to - // access the highest level. Others are there in case we need - // to back out. - filterTreeMap = new TreeMap( - LocalizationLevel.REVERSE_COMPARATOR ); - rscFiltersMap.put( rdName, filterTreeMap ); - } + // if deleting or updating then + // remove all of the entries in the map at this + // localization lvl + // + if (msg.getChangeType() == FileChangeType.DELETED + || msg.getChangeType() == FileChangeType.UPDATED) { - filterTreeMap.put( lLvl, rFilt ); - } - } - } + for (String rdName : rscFiltersMap.keySet()) { + TreeMap filtMap = rscFiltersMap + .get(rdName); + filtMap.remove(msg.getContext() + .getLocalizationLevel()); + } + } - // - private void readResourceDefns() throws VizException { - if( resourceDefnsMap != null ) { - return; - } - - Collection supportedPlugins = RecordFactory.getInstance().getSupportedPlugins(); - - // this was used to maintain the order in the resourceDefnsTable but now that - // these are separate files, I don't know that this will work. Need to - // find another way to get these in the right order for the GUI. - long t0 = System.currentTimeMillis(); + // if adding or updating, reread the file. + if (msg.getChangeType() == FileChangeType.ADDED + || msg.getChangeType() == FileChangeType.UPDATED) { - Map lFiles = pathMngr.listFiles( - NcPathConstants.RSC_DEFNS_DIR, new String[]{ "xml" }, true, true ); + try { + LocalizationFile locFile = NcPathManager + .getInstance() + .getLocalizationFile( + msg.getContext(), + msg.getFileName()); - if( lFiles.containsKey( NcPathConstants.RESOURCE_FILTERS ) ) { - lFiles.remove( NcPathConstants.RESOURCE_FILTERS ); + readRscFilter(locFile); + + } catch (SerializationException e) { + } + } + } + }); + + try { + readRscFilter(rscFiltersLFile); + } catch (SerializationException e) { + rscDefnsWarningsList.add(new VizException(e)); + System.out.println("error serializing" + + rscFiltersLFile.getFile().getAbsolutePath() + + " : " + e.getMessage()); + } + } + + // loop thru all the RDs and if there is no entry in the filters + // map, add one + // at the same level as the RD. + // + for (ResourceDefinition rd : resourceDefnsMap.values()) { + String rdName = rd.getResourceDefnName(); + + TreeMap filterTreeMap = rscFiltersMap + .get(rdName); + + if (filterTreeMap == null) { + filterTreeMap = new TreeMap( + LocalizationLevel.REVERSE_COMPARATOR); + filterTreeMap.put(rd.getLocalizationFile().getContext() + .getLocalizationLevel(), + new ResourceDefinitionFilter(rdName, + dfltEnableState, null, rd + .getLocalizationFile().getContext() + .getLocalizationLevel())); + rscFiltersMap.put(rdName, filterTreeMap); + + // if there a filters file then this one is just missing for + // some reason. + if (filtFiles != null) { + rscDefnsWarningsList + .add(new VizException( + "Could not find the Rsc Defn," + + rdName + + ", in any ResourceDefintionFilters files." + + " it will be Enabled by default.")); + } + } + } + } + + return; + } + + private void readRscFilter(LocalizationFile locFile) + throws SerializationException { + String fileName = locFile.getFile().getAbsolutePath(); + LocalizationLevel lLvl = locFile.getContext().getLocalizationLevel(); + + synchronized (rscFiltersMap) { + ResourceDefinitionFilters rscDfnFilters = SerializationUtil + .jaxbUnmarshalFromXmlFile(ResourceDefinitionFilters.class, + fileName); + + for (ResourceDefinitionFilter rFilt : rscDfnFilters + .getResourceDefinitionFiltersList()) { + String rdName = rFilt.getRscDefnName(); + rFilt.setLocLevel(lLvl); + + TreeMap filterTreeMap = rscFiltersMap + .get(rdName); + + // if there is already an entry in the map, add this one to th + if (filterTreeMap == null) { + // store entries in reverse order since we only want to + // access the highest level. Others are there in case we + // need + // to back out. + filterTreeMap = new TreeMap( + LocalizationLevel.REVERSE_COMPARATOR); + rscFiltersMap.put(rdName, filterTreeMap); + } + + filterTreeMap.put(lLvl, rFilt); + } + } + } + + // + private void readResourceDefns() throws VizException { + if (resourceDefnsMap != null) { + return; + } + + Collection supportedPlugins = RecordFactory.getInstance() + .getSupportedPlugins(); + + // this was used to maintain the order in the resourceDefnsTable but now + // that + // these are separate files, I don't know that this will work. Need to + // find another way to get these in the right order for the GUI. + long t0 = System.currentTimeMillis(); + + Map lFiles = pathMngr.listFiles( + NcPathConstants.RSC_DEFNS_DIR, new String[] { "xml" }, true, + true); + + if (lFiles.containsKey(NcPathConstants.RESOURCE_FILTERS)) { + lFiles.remove(NcPathConstants.RESOURCE_FILTERS); } // Create the map resource definitions - // - resourceDefnsMap = new HashMap(); + // + resourceDefnsMap = new HashMap(); - for( LocalizationFile lFile : lFiles.values() ) { - try { - readResourceDefn( lFile ); - - - // TODO : add localization observer to update the Map when a localization file has - // changed on another cave. - lFile.addFileUpdatedObserver( new ILocalizationFileObserver() { - @Override - public void fileUpdated(FileUpdatedMessage message) { - - System.out.println("Localization File for RD, "+message.getFileName()+" has been updated.\n"+ - "To get these changes you will need to restart cave."); -// VizApp.runAsync(new Runnable() { -// @Override -// public void run() { -// MessageDialog warnDlg = new MessageDialog( -// .getShell(), "WARNING", null, , MessageDialog., -// new String[] { "OK" }, 0); -// warnDlg.open(); -// } -// }); - } - }); - } - catch ( VizException e ) { - out.println("Error creating ResourceDefn from file: "+lFile.getName() ); - out.println(" --->"+e.getMessage() ); - badRscDefnsList.add( e ); - } - } - - long t1 = System.currentTimeMillis(); - out.println("Time to read "+lFiles.values().size() +" Resource Definitions: " + (t1-t0) + " ms"); + for (LocalizationFile lFile : lFiles.values()) { + try { + readResourceDefn(lFile); - // read in the rscFiltersMap, - try { - readResourceFilters(); - } - catch( VizException e ) { - - } - - // Note: Temporary solution. Would prefer to fold this into the referencing - // attr set file if/when changed to xml format. - // - t0 = System.currentTimeMillis(); - - readRefParamFiles(); - - t1 = System.currentTimeMillis(); - out.println("Time to read colorbars: " + (t1-t0) + " ms"); - - // read in the attrSetGroupsMap (this needs the resourceDefnsMap - // to be set.) - // - readAttrSets( ); - long t2 = System.currentTimeMillis(); - - out.println("Time to read Attr Sets: " + (t2-t1) + " ms"); + // TODO : add localization observer to update the Map when a + // localization file has + // changed on another cave. + lFile.addFileUpdatedObserver(new ILocalizationFileObserver() { + @Override + public void fileUpdated(FileUpdatedMessage message) { - List errRdsList = findOrCreateInventoryForRscDefns( resourceDefnsMap.values() ); - - // loop thru the ResourceDefns and enable those that have been initialized and - // find any inventories that don't exist and create them - // - - for( String rmRd : errRdsList ) { - resourceDefnsMap.remove( rmRd ); - } - } - - private void readResourceDefn( LocalizationFile lFile ) throws VizException { - - File rscDefnFile = lFile.getFile(); - - try { - ResourceDefinition rscDefn = SerializationUtil.jaxbUnmarshalFromXmlFile( - ResourceDefinition.class, rscDefnFile.getAbsolutePath() ); - - // TODO : If the definitions are modified and written out, this will drop any invalid resourceDefns. - // Should we save these write them out anyway? Make them disabled? - - // Validate that the resource implementation is present and that the - // parameters are defined - // - String rscImpl = rscDefn.getRscImplementation(); - - if( !ResourceExtPointMngr.getInstance().getAvailResources().contains( rscImpl ) ) { - throw new VizException("The Resource implementation: "+ rscImpl +" for "+ - rscDefn.getResourceDefnName()+" is not " + - "specified in a NC-Resource extention point" ); - } - else { - rscDefn.validateResourceParameters(); - - if( resourceDefnsMap.containsKey( rscDefn.getResourceDefnName() ) ) { - throw new VizException("Failed to create Rsc Defn '"+rscDefn.getResourceDefnName()+ - "' from file: "+rscDefnFile.getAbsolutePath()+ " because there is another Rsc Defn with this name."); - } - - if( rscDefn.isRequestable() ) { - if( rscDefn.getPluginName() == null ) { - throw new VizException( "Failed to create Rsc Defn "+rscDefn.getResourceDefnName()+ - ": Requestable Resource is missing required pluginName parameter"); - } - - if( !RecordFactory.getInstance(). - getSupportedPlugins().contains( rscDefn.getPluginName() ) ) { - rscDefnsWarningsList.add( - new VizException( "Disabling "+ rscDefn.getResourceDefnName()+ - " because plugin, "+ rscDefn.getPluginName()+ - " is not activated." ) ); - } - } - - resourceDefnsMap.put( rscDefn.getResourceDefnName(), rscDefn ); - - if( rscImpl.equals( "Locator" ) ) { - locatorRscDefn = rscDefn; - } - - // TODO : Change this to set the LocalizationFile or the context - rscDefn.setLocalizationFile( lFile ); - -// if( rscDefn.usesInventory() ) { -// -// NcInventoryDefinition invDefn = -// rscDefn.createNcInventoryDefinition(); -// -// // throws exception on error creating a defn -// if( invDefnsMap.containsKey( invDefn ) ) { -// -// rscDefn.setInventoryAlias( -// invDefnsMap.get( invDefn ).getInventoryName() ); -// } -// } - } - } - catch (SerializationException e) { - throw new VizException("Error parsing "+rscDefnFile.getAbsolutePath() +" - " + e.getMessage() ); - } - catch (Exception e ) { - throw new VizException( "Error parsing "+rscDefnFile.getAbsolutePath() +" - " + e.getMessage() ); - } - } - - private void readRefParamFiles( ) { - refdParamFilesMap = new HashMap(); - - // This will find all .xml (must be AttrSetGroup xml files) for all - // of the Resource implementations. - // - - for( String refDir : refdParamDirectories ) { - - Map lclFiles = pathMngr.listFiles( - refDir, new String[]{ ".xml" }, true, false ); - - if( lclFiles.isEmpty() ) { - out.println("Error finding Files in "+refDir+" for parameter references?"); - continue; - } - - // - for( LocalizationFile lclFile : lclFiles.values() ) { - - // get the resource implementation from the path. -// String lName = lclFile.getName(); -// lName = lName.substring( NcPathConstants.NCEP_ROOT.length() ); - // cbarName = cbarName.substring( 0, cbarName.length()-".xml".length() ); - - lclFile.addFileUpdatedObserver( new ILocalizationFileObserver() { - @Override - public void fileUpdated(FileUpdatedMessage fumsg) { - String fName = fumsg.getFileName(); - LocalizationFile lFile; - - // if the file had been deleted - if( fumsg.getChangeType() == FileChangeType.DELETED ) { - refdParamFilesMap.remove( fName ); - // if reverted. (ie DELETED and there is a lower level file available) - lFile = pathMngr.getStaticLocalizationFile( fumsg.getFileName() ); - } - else { - // get the ADDED, UPDATED file - lFile = pathMngr.getLocalizationFile( - fumsg.getContext(), fumsg.getFileName() ); - } - - // update the map with the new file - if( lFile != null ) { - refdParamFilesMap.put( fName, lFile ); - } - } - }); - - if( !lclFile.isDirectory() ) { - // TODO : should we unmarsh here to validate? - // - refdParamFilesMap.put( lclFile.getName(), lclFile ); - } -// else { -// out.println("Adding observer to LFile "+lclFile.getContext()+":"+lclFile.getName() ); -// } - } - } - } - - // initialize the attrSetMap and the attrSetGroupsMap - // - private void readAttrSets( ) throws VizException { - - attrSetGroupsMap = new HashMap(); - - // This will find all .xml (must be AttrSetGroup xml files) for all - // of the Resource implementations. - // - Map attrSetGrpLclFiles = pathMngr.listFiles( - NcPathConstants.ATTR_SET_GROUPS_DIR, - new String[]{ ".xml" }, true, true ); - - if( attrSetGrpLclFiles.isEmpty() ) { - out.println("Error finding AttrSetGroup Files?"); - return; + System.out.println("Localization File for RD, " + + message.getFileName() + + " has been updated.\n" + + "To get these changes you will need to restart cave."); + // VizApp.runAsync(new Runnable() { + // @Override + // public void run() { + // MessageDialog warnDlg = new MessageDialog( + // .getShell(), "WARNING", null, , MessageDialog., + // new String[] { "OK" }, 0); + // warnDlg.open(); + // } + // }); + } + }); + } catch (VizException e) { + out.println("Error creating ResourceDefn from file: " + + lFile.getName()); + out.println(" --->" + e.getMessage()); + badRscDefnsList.add(e); + } } - - // the sub-dirs under the attrSetGroups dir must match a resourceImplClass - // - // check that the naming convention is used. If not then there can be a potential problem if the - // group is edited since it will be given a different localization Name. - - for( LocalizationFile lclFile : attrSetGrpLclFiles.values() ) { - - // TODO : add localization observer to update the Map when a localization file has - // changed on another cave. - - File asgFile = lclFile.getFile(); - - if( !asgFile.exists() ) { - out.println( "Can't open AttrSetGroup file: "+asgFile.getAbsolutePath() ); - continue; - } - AttrSetGroup asg; - try { - asg = SerializationUtil.jaxbUnmarshalFromXmlFile( AttrSetGroup.class, asgFile.getAbsolutePath( ) ); - - } catch (SerializationException e) { - throw new VizException("Error Parsing file "+asgFile.getAbsolutePath( ) +"\n"+e.getMessage()); - } - // add the ASG's in the list to the map. (PGEN is a special case since - // 1 'default' ASG applies to all PGEN resources.) - asg.setLocalizationFile( lclFile ); + long t1 = System.currentTimeMillis(); + out.println("Time to read " + lFiles.values().size() + + " Resource Definitions: " + (t1 - t0) + " ms"); - // if not PGEN then - // validate that there is a resourceImpl for this attrSetGroup - // - if( !asg.getRscAndGroupName().isPGEN() ) { + // read in the rscFiltersMap, + try { + readResourceFilters(); + } catch (VizException e) { - ResourceDefinition asgRscDefn = getResourceDefinition( asg.getResource() ); - if( asgRscDefn == null ) { - out.println("AttrSetGroup file "+ - asgFile.getName() +" has a unknown resource:"+ - asg.getResource() ); - continue; - } - - String rscImpl = asgRscDefn.getRscImplementation(); + } - if( !ResourceExtPointMngr.getInstance(). - getAvailResources().contains( rscImpl ) ) { - out.println( "Can't find Resource Implementation (class) for " + - "attrSetGroup : " + rscImpl ); + // Note: Temporary solution. Would prefer to fold this into the + // referencing + // attr set file if/when changed to xml format. + // + t0 = System.currentTimeMillis(); - out.println( "The Resource implementation should be specified in " + - "a NC-Resource extention point" ); - // don't fail; go ahead and put the attrset in the map - } - - // check that the file name follows the convention otherwise there could be a - // problem if the user edits it since the name for the USER-level file will be - // different and not recognized as the same group. - // - String lFileName = NcPathConstants.ATTR_SET_GROUPS_DIR + File.separator + rscImpl + - File.separator + asg.getResource()+"-"+asg.getAttrSetGroupName()+".xml"; - - if( !lFileName.equals( lclFile.getName() ) ) { - out.println("Warning: Localization file for AttrSetGroup, "+ lclFile.getName() + - " doesn't follow the naming convention.("+lFileName+")" ); - } - } + readRefParamFiles(); - if( attrSetGroupsMap.containsKey( asg.getRscAndGroupName().toString() ) ) { - System.out.println(asg.getRscAndGroupName().toString()+" already in the map???"); - - } + t1 = System.currentTimeMillis(); + out.println("Time to read colorbars: " + (t1 - t0) + " ms"); - // - attrSetGroupsMap.put( asg.getRscAndGroupName().toString(), asg ); - } - - // Next set the attrSetMap. - - // This is a map from the resource type or rsc impl to a map of the available attribute sets - attrSetMap = new HashMap>(); - - // first get the attrSets for the AttrSetGroups. - // In this case the key is the resource Implementation instead of the resource type - // - Map attrSetLclFiles = - pathMngr.listFiles( - NcPathConstants.ATTR_SET_GROUPS_DIR, - new String[]{ ATTR_SET_FILE_EXT }, true, true ); + // read in the attrSetGroupsMap (this needs the resourceDefnsMap + // to be set.) + // + readAttrSets(); + long t2 = System.currentTimeMillis(); - if( attrSetLclFiles.isEmpty() ) { - out.println("Error finding AttrSets (for AttrSetGroups) Files?"); - return; - } + out.println("Time to read Attr Sets: " + (t2 - t1) + " ms"); - // the sub-dirs under attrSetGroups must match a resourceImplClass - // - for( LocalizationFile asLclFile : attrSetLclFiles.values() ) { + List errRdsList = findOrCreateInventoryForRscDefns(resourceDefnsMap + .values()); - // get the resource implementation from the path. -// String asLclName = asLclFile.getName().substring( ATTR_SET_GROUPS_DIR.length()+1 ); -// String rscImpl = asLclName.substring( 0, -// asLclName.indexOf( File.separator ) ); -// String attrSetName = asLclName.substring(rscImpl.length()+1, -// asLclName.length()-ATTR_SET_FILE_EXT.length() ); - String rscImpl = asLclFile.getFile().getParentFile().getName(); -// String attrSetName = asLclFile.getFile().getName(); -// attrSetName = attrSetName.substring(0, -// attrSetName.length()-ATTR_SET_FILE_EXT.length() ); -// ArrayList rscTypes = getRscTypesForRscImplementation( rscImpl ); + // loop thru the ResourceDefns and enable those that have been + // initialized and + // find any inventories that don't exist and create them + // - if( !attrSetMap.containsKey( rscImpl ) ) { - attrSetMap.put( rscImpl, new HashMap() ); - } - try { - AttributeSet aSet = AttributeSet.createAttributeSet(rscImpl, asLclFile ); - - attrSetMap.get( rscImpl ).put( aSet.getName(), aSet ); - } - catch ( VizException e ) { - out.println("Error Creating AttributeSet "+ asLclFile.getName() + - ": "+ e.getMessage() ); - } - } - - // Next get the attrSets for other resources which have attribute sets of their own. - // In this case the key is the resource type name. - // - attrSetLclFiles = pathMngr.listFiles( NcPathConstants.RSC_DEFNS_DIR, - new String[]{ ATTR_SET_FILE_EXT }, true, true ); - - if( attrSetLclFiles.isEmpty() ) { - out.println("Error finding AttrSet Files?"); - return; - } - - for( LocalizationFile asLclFile : attrSetLclFiles.values() ) { - -// if( asLclFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { -// out.println(" USER"); -// } - // Some resources may have more organizational directories than others. The resource - // type is the lowest directory. - String dirs[] = asLclFile.getName().split( File.separator ); - if( dirs == null || dirs.length < 3 ) { - continue; // ????? - } - -// String attrSetName = dirs[ dirs.length-1 ]; -// attrSetName = attrSetName.substring( 0, attrSetName.length()-ATTR_SET_FILE_EXT.length() ); - - String rscType = dirs[ dirs.length-2 ]; - - if( !attrSetMap.containsKey( rscType ) ) { - attrSetMap.put( rscType, new HashMap() ); - } - - try { - AttributeSet aSet = AttributeSet.createAttributeSet(rscType, asLclFile ); - - attrSetMap.get( rscType ).put( aSet.getName(), aSet ); - } - catch ( VizException e ) { - out.println("Error Creating AttributeSet "+ asLclFile.getName()+ - ": "+ e.getMessage() ); - } - } - - // validate that the attrSets referenced from the attrSetGroups actually exist - // (PGEN is a special case) - for( AttrSetGroup asg : attrSetGroupsMap.values() ) { - - String rscType = asg.getResource(); - String attrSetMapKey=""; - - if( asg.getRscAndGroupName().isPGEN() ) { - attrSetMapKey = asg.getResource(); - } - else { - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - if( rscDefn != null ) { - attrSetMapKey = rscDefn.getRscImplementation(); - } - } - - for( String asName : new ArrayList( asg.getAttrSetNames()) ) { - if( !attrSetMap.containsKey( attrSetMapKey ) || - !attrSetMap.get( attrSetMapKey ).containsKey( asName ) ) { - - asg.removeAttrSet(asName); - out.println("attrSet "+asName+" in attrSetGroup "+ - asg.getResource()+File.separator+asg.getAttrSetGroupName()+" doesn't exist."); - } - } - } - } - - public List findOrCreateInventoryForRscDefns( Collection rscDefnsToSetup ) { - // loop thru the ResourceDefns and enable those that have been initialized and - // find any inventories that don't exist and create them - // - // This would read the inventoryDefns from localizations (ie what edex uses) - // to initialize but instead we will query edex to see what's there and - // only create inventories that don't exist. -// checkAndSaveNcInventories(); - Map invDefnsMap = null; - - // its possible this is failing/empty on the testbed for some unknown - // reason. Since this will cause 'duplicate' ID to be created we should - // retry to make sure. - for( int tryCount=1 ; tryCount<=5 ; tryCount++ ) { - try { - invDefnsMap = getInventoryDefinitions(); - - if( invDefnsMap == null || invDefnsMap.isEmpty() ) { - throw new VizException( "Inventory Directory is Empty?"); - } - else { - break; - } - } - catch (VizException ve ) { - System.out.println( "Error getting NcInventory Directory" + ve.getMessage() ); - try { Thread.sleep(1000); } catch (InterruptedException e) { } - } - } - - if( invDefnsMap == null ) { - invDefnsMap = new HashMap(); - } - - List createInvDefns = new ArrayList(); - List errList = new ArrayList(); - - for( ResourceDefinition rd : rscDefnsToSetup ) { - try { - HashMap rc = - rd.getInventoryConstraintsFromParameters( - rd.getResourceParameters( true ) ); - List reqParams = rd.getUnconstrainedParameters(); - reqParams.add( "dataTime" ); - - for( NcInventoryDefinition edexID : invDefnsMap.keySet() ) { - if( edexID.supportsQuery( rc, reqParams ) ) { - if( rd.isInventoryInitialized() ) { - System.out.println( "RD "+ rd.getResourceDefnName() + - " has more than one supporting ID, "+ rd.getInventoryAlias()+ - " and "+ edexID.getInventoryName() ); - } - System.out.println("Inventory found for "+ rd.getResourceDefnName() + " is " + - edexID.getInventoryName() ); - rd.setInventoryAlias( edexID.getInventoryName() ); -// break; - } - } - - if( rd.usesInventory() && - rd.getInventoryEnabled() && - !rd.isInventoryInitialized() ) { - - createInvDefns.add( rd.createNcInventoryDefinition() ); - } - } - catch ( VizException e ) { - out.println("Error creating ResourceDefn from file: "+rd.getLocalizationFile().getName() ); - out.println(" --->"+e.getMessage() ); - badRscDefnsList.add( e ); - } - } - - if( !createInvDefns.isEmpty() ) { - InventoryLoaderJob invLoader = new InventoryLoaderJob( createInvDefns, false ); - - invLoader.schedule(); - - // TODO : update the progress monitor - while( invLoader.getNumberOfInventoriesLeftToLoad() > 0 ) { - // out.println("Inventories left to load = "+invLoader.getNumberOfInventoriesLeftToLoad() ); - try { - Thread.sleep(400); - } catch (InterruptedException e) { - } - } - - errList = Arrays.asList( invLoader.getUninitializedInventoryDefns() ); - } - - List errRdsList = new ArrayList(); - - // for the rscDefns that just had an inventory created for them - // enable or disable based on whether there was an error. - // - for( ResourceDefinition rd : resourceDefnsMap.values() ) { - - if( rd.usesInventory() ) { - try { - NcInventoryDefinition invDefn = rd.createNcInventoryDefinition(); - - // if created successfully set the inventoryName/Alias - if( createInvDefns.contains( invDefn ) && - !errList.contains( invDefn ) ) { - - rd.setInventoryAlias( invDefn.getInventoryName() ); - } - - // if there is an inventory and if it is enabled - if( rd.getInventoryEnabled() && - !errList.contains( invDefn ) ) { - - rd.enableInventoryUse(); // remove the ProductAlertObserver - } - else { - rd.disableInventoryUse(); // add the ProductAlertObserver and query types/subTypes - } - } - catch ( VizException e ) { -// rd.setInventoryEnabled(false); -// setResourceEnable( rd.getResourceDefnName(), false ); - errRdsList.add( rd.getResourceDefnName() ); - - out.println("Error creating ResourceDefn : "+rd.getResourceDefnName() ); - out.println(" --->"+e.getMessage() ); - badRscDefnsList.add( - new VizException( "Error creating ResourceDefn : "+rd.getResourceDefnName()+ " : " + e.getMessage() )); - } - } - } - - return errRdsList; - } - - // a list of inventories definitions available on edex. - // used to set the inventoryInitialized flag. - public Map getInventoryDefinitions() throws VizException { - - Map invDefnsMap = null; - - // query the list of inventories that exist on edex and set the - // inventoryInitialized flag in the ResourceDefns - NcInventoryRequestMsg dirRequest = NcInventoryRequestMsg.makeDirectoryRequest(); - - Object rslts = ThriftClient.sendRequest( dirRequest ); - - if( rslts instanceof String ) { - throw new VizException( rslts.toString() ); - } - if( !(rslts instanceof ArrayList) ) { - throw new VizException( "Inventory Directory Request Error: expecting ArrayList." ); - } - else if( ((ArrayList)rslts).isEmpty() ) { - out.println("Inventory Directory Request Warning: No Inventories initialized.???" ); - } - else if( !(((ArrayList)rslts).get(0) instanceof NcInventoryDefinition) ) { - throw new VizException( "Inventory Directory Request Error: expecting ArrayList." ); - } - - // used to set the inventory initialized flag - ArrayList invDefnsList = (ArrayList)rslts; - - invDefnsMap = new HashMap(); - - for( NcInventoryDefinition invDefn : invDefnsList ) { - invDefnsMap.put( invDefn, invDefn ); - } - - return invDefnsMap; - } - - public boolean isResourceNameValid( ResourceName rscName ) { - if( rscName == null || - rscName.getRscCategory() == null || - rscName.getRscCategory() == ResourceCategory.NullCategory || - rscName.getRscType() == null || - rscName.getRscType().isEmpty() || - rscName.getRscAttrSetName() == null || - rscName.getRscAttrSetName().isEmpty() ) { - - return false; - } - - ResourceDefinition rd = getResourceDefinition( rscName ); - - if( rd == null ) { - return false; - } - - // if there is a generating type then check for a ':' - // - if( !rd.getRscTypeGenerator().isEmpty() ) { - if( rscName.getRscType().indexOf( - ResourceName.generatedTypeDelimiter ) == -1 ) { -// out.println("ResourceName "+rscName.toString() + " is expecting a "+ -// "generated type from the "+ rd.getRscTypeGenerator() ); - return false; - } - } - // if there is no group/subType, make sure there isn't supposed to be one. - if( rscName.getRscGroup() == null || - rscName.getRscGroup().isEmpty() ) { - - if( rd.applyAttrSetGroups() || !rd.getSubTypeGenerator().isEmpty() ) { -// out.println("ResourceName "+rscName.toString() + " is expecting a "+ -// "generated sub-type from "+ rd.getSubTypeGenerator() ); - return false; - } - } - else { // and if there is one - - } - - return true; - } - - // similar to validateResourceParameters except we are also checking for the attributes -// public void verifyParametersExist( ResourceName rscName ) throws VizException { -// ResourceDefinition rscDefn = getResourceDefinition( rscName.getRscType() ); -// -// if( rscDefn == null ) { -// throw new VizException("Unable to find resource definition for "+rscName.toString() ); -// } -// -// rscDefn.validateResourceParameters(); -// -// HashMap rscImplParams = -// ResourceExtPointMngr.getInstance().getResourceParameters( rscDefn.getRscImplementation() ); -// -// // the default values specified in the extention point -// HashMap dfltParamValues = rscDefn.getDefaultParameterValues(); -// -// // the parameters defined by the resource definition -// HashMap paramValues = getAllResourceParameters( rscName ); -// -// // a list of all the generated parameters -// List genParamsList = new ArrayList( Arrays.asList( rscDefn.getSubTypeGenParamsList() ) ); -// if( !rscDefn.getRscTypeGenerator().isEmpty() ) { -// genParamsList.add( rscDefn.getRscTypeGenerator() ); -// } -// -// // check that all the parameters defined for the implmentation either have a -// // value given in the rsc params, will be generated, or have a default value -// // -// for( ResourceParamInfo implPrmInfo : rscImplParams.values() ) { -// String implPrm = implPrmInfo.getParamName(); -// String prmConstraintName = implPrmInfo.getConstraintName();// same as paramName except for GDFILE and 1 or 2 others. -// -// if( implPrmInfo.getParamType() == ResourceParamType.EDITABLE_ATTRIBUTE || -// implPrmInfo.getParamType() == ResourceParamType.NON_EDITABLE_ATTRIBUTE ) { -// -// // if the needed param is not set in the resource defn or is set to empty -// String paramValue = paramValues.get( implPrm ); -// -// if( paramValue == null || paramValue.isEmpty() ) { -// -// paramValue = dfltParamValues.get( implPrm ); -// -// // if there is no default value specified by the implementation -// // -// if( paramValue == null || paramValue.isEmpty() ) { -// throw new VizException( rscDefn.getResourceDefnName()+ -// " is missing a value for the attribute "+implPrm+"." ); -// } -// else { -// out.println("Setting attribute "+implPrm+" to default value "+paramValue ); -// } -// } -// } -// -// // if this is not a generated request constraint, then check the inventory to make -// // sure that this value is in the database -// // -// else if( implPrmInfo.getParamType() == ResourceParamType.REQUEST_CONSTRAINT ) { -// // if there is not a value for this parameter -// // -// if( !paramValues.containsKey( implPrm ) ) { -// throw new VizException( -// "The parameter "+implPrm+" is not available for resource "+ rscDefn.getResourceDefnName()+"." ); -// } -// -// // if this parameter is in the inventory then see if we need to -// // see if the value (given in the selected attrSet) is in the inventory. -// // -// if( rscDefn.getInventoryParameterNames().contains( prmConstraintName ) ) { -// -// // if this is not a generated parameter -// // (assume that since it was generated then it must be in the inventory, -// // currently this is true but may not be if this method is ever -// // called from other than updateSelectedResource.) -// // -// if( !genParamsList.contains( prmConstraintName ) ) { -// -// ArrayList qRslts = rscDefn.queryInventoryParameter( rscName, prmConstraintName ); -// -// if( qRslts.isEmpty() ) { -// throw new VizException( -// "The parameter value "+implPrm+"="+paramValues.get(implPrm)+ -// " is not available for resource "+ rscDefn.getResourceDefnName()+"." ); -// } -// -// out.println("Inventory has "+ qRslts.size() +" values"); -// } -// } -// } -// } -// -// // check that all of the paramValues are specified for the rsc implementation -// // -// for( String prm : paramValues.keySet() ) { -// if( !prm.equals("pluginName") && -// !paramInfoForRscDefnParamsMap.containsKey( prm ) && -// !rscImplParams.containsKey( prm ) ) { -// -// // out.println("Warning: parameter "+prm+" for "+getResourceDefnName()+ -// // " is not recognized for the resource implementation "+getRscImplementation() ); -// -// throw new VizException( rscDefn.getResourceDefnName()+" has a parameter, "+prm+ -// ", that is not recognized by its implementation: "+ rscDefn.getRscImplementation() ); -// } -// } -// } - - - public ResourceDefinition getResourceDefinition( ResourceName rscName ) { - return (rscName != null ? getResourceDefinition( rscName.getRscType() ) : null); - } - - public boolean findResourceDefinition( String rscType ) { - if( resourceDefnsMap.containsKey( rscType ) ) { - return true; - } - - // allow for generated types which will have a ':' - // - int indx = rscType.indexOf(":"); - - if( indx == -1 ) { - return false; - } - - return resourceDefnsMap.containsKey( rscType.substring( 0, indx ) ); - } - - public ResourceDefinition getResourceDefinition( String rscType ) { - if( resourceDefnsMap.containsKey( rscType ) ) { - return resourceDefnsMap.get( rscType ); - } - - // allow for generated types which will have a ':' - // - int indx = rscType.indexOf(":"); - - if( indx != -1 ) { - if( resourceDefnsMap.containsKey( rscType.substring( 0, indx ) ) ) { - return resourceDefnsMap.get( rscType.substring( 0, indx ) ); - } - } - -// out.println("sanity check: can't find ResourceDefinition for: "+rscType ); - return null; - } - - // defined as an array but for now only assume 1 disp type in the list. - public ResourceCategory[] getResourceCategories( boolean includeDisabled, NcDisplayType[] matchingDispTypes ) { - - if( matchingDispTypes.length != 1 ) { - System.out.println("getResourceCategories called with more than one display type. Only matching the first one"); - } - - ArrayList catsList = new ArrayList(); - - // loop thru all the available categories in order and if a resource defn - // exists for it then - for( ResourceCategory rc : ResourceCategory.values() ) { - - for( ResourceDefinition rscDefn : resourceDefnsMap.values() ) { - - if( rc == rscDefn.getResourceCategory() ) { - - if( includeDisabled || rscDefn.isEnabled() ) { - - if( rscDefn.isDisplayTypeSupported( matchingDispTypes[0] ) ) { - - if( !catsList.contains( rc ) ) { - catsList.add( rc ); - break; - } - } - } - } - } - } - - ResourceCategory[] catsArray = catsList.toArray( new ResourceCategory[0] ); -// -// Arrays.sort( catsArray, new Comparator() { -// public int compare(String o1, String o2) { -// int indx1 = availResourceCategoriesList.indexOf( (String)o1 ); -// int indx2 = availResourceCategoriesList.indexOf( (String)o2 ); -// -// return ((indx1 == indx2 ? 0 : (indx1 < indx2 ? -1 : 1 ))); -// } -// }); - - return catsArray; - -// return catsList.toArray( new String[0] ); -// return ResourceCategories; - } - - // map the Full Resource Name to the location of the resource bundle template file - // for the resource. - // The rsc name is the RBD Category/Type/Group/AttributeSet. The fcst/obs is not saved - // so we try both to find a match. - public File getRscBundleTemplateFile( String rscType ) { - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - - if( rscDefn == null ) { - return null; - } - - // get the name of the NC resource which will implement the resource - String rscImplName = rscDefn.getRscImplementation(); - - if( !rscImplName.endsWith(".xml") ) { - rscImplName = rscImplName + ".xml"; - } - File rscTemplateFile = pathMngr.getStaticFile( - NcPathConstants.RSC_TMPLTS_DIR+File.separator+rscImplName ); - - return ( rscTemplateFile.exists( ) ? rscTemplateFile : null ); - } - - // - public boolean doesResourceUseAttrSetGroups( String rscType ) { - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - - return ( rscDefn == null ? false : rscDefn.applyAttrSetGroups() ); - } - - // - // - public String getDefaultFrameTimesSelections( ResourceName rscName ) throws VizException { - ResourceDefinition rscDefn = getResourceDefinition( rscName.getRscType() ); - - if( rscDefn == null ) { - return null; - } - - HashMap paramsMap = new HashMap( rscDefn.getResourceParameters(false) ); - - AttributeSet attrSet = getAttrSet( rscName ); - - if( attrSet != null ) { - paramsMap.putAll( attrSet.getAttributes() ); - } - - if( paramsMap.containsKey("GDATTIM" ) ) { - - // check syntax - new SelectableFrameTimeMatcher( paramsMap.get("GDATTIM") ); - - return paramsMap.get("GDATTIM"); - } - else { - return null; - } - } - - // get the Attribute Set File for the given resource name. This may either - // be in the AttrSetGroup directory or directly under the resources config dir. - - // Get all parameters needed to instantiate the bundle template - // This includes parameters from the ResourceDefinition, attributes and timeMatching/frameCount... - // - public HashMap getAllResourceParameters( ResourceName rscName ) throws VizException { - - ResourceDefinition rscDefn = getResourceDefinition( rscName.getRscType() ); - - if( rscDefn == null ) { - return null; - } - - // first get the parameters defined by the RscDefn and use the default values - // for any that are not present. - HashMap paramsMap = new HashMap( rscDefn.getResourceParameters(true) ); - - // next get the attributes - AttributeSet attrSet = getAttrSet( rscName ); - - if( attrSet != null ) { - paramsMap.putAll( attrSet.getAttributes() ); - } - - if( paramsMap.containsKey("GDATTIM") ) { - paramsMap.remove("GDATTIM"); - } - - // and now create the parameters from the rscDefinitions file. - // (frameInterval, timeMatchMethod) - if( rscDefn.getResourceCategory() != ResourceCategory.OverlayRscCategory ) { - - paramsMap.put("frameSpan", Integer.toString( rscDefn.getFrameSpan() ) ); - paramsMap.put("timeMatchMethod", rscDefn.getTimeMatchMethod().toString() ); - paramsMap.put("dfltNumFrames", Integer.toString( rscDefn.getDfltFrameCount())); - paramsMap.put("dfltTimeRange", Integer.toString( rscDefn.getDfltTimeRange()) ); - paramsMap.put("timelineGenMethod", rscDefn.getTimelineGenMethod().toString() ); - paramsMap.put("isForecast", (rscDefn.isForecast() ? "true" : "false" ) ); - } - - // if this is a generated type get the parameter value from the type in the ResourceName - // - String typeGenParam = rscDefn.getRscTypeGenerator(); - - if( !typeGenParam.isEmpty() ) { - - String rscType = rscName.getRscType(); - int indx = rscType.indexOf(":"); - if( indx == -1 ) { - throw new VizException("sanity check: Can't parse generated typ from "+ - "Resource name :"+rscName.toString() ); - } - - String typeName = rscType.substring( indx+1 ); - - paramsMap.put( typeGenParam, typeName ); - } - - // If there is a generated sub-type then we will need to set a parameter for this - // (In this case the name of the parameter in the paramsMap must be the same as the - // name of the variable in the BundleTemplate.) - // - String[] subTypeGenParams = rscDefn.getSubTypeGenParamsList(); - - if( subTypeGenParams.length == 1 ) { - paramsMap.put( subTypeGenParams[0], rscName.getRscGroup() ); - } - - // TODO : Note this currently only works for Satellite because its - // the only resource that uses 2 generating params, (the area and resolution) - // A trailing 'km' which means this parsing code is not generic - // - else if( subTypeGenParams.length == 2 ) { - - String subType = rscName.getRscGroup(); - //if( !subType.endsWith( "km" ) ) { - // out.println("Sanity check : SubType "+subType +" is expected to end with 'km'"); - //} - - int indx = subType.lastIndexOf( '_' ); - if( indx != -1 ) { - String paramVal1 = subType.substring(0, indx); - String paramVal2 = subType.endsWith( "km" ) ? - subType.substring(indx+1, subType.length()-2) // NOTE; "km" - : subType.substring(indx+1, subType.length()); - // TODO : get rid of these hacks and redesign the resoureName <-> parameter value mapping - if( paramVal2.equals("native") ) { - paramVal2 = "0"; - } - // TODO -- Can't make following sanity-check / cleanup anymore because paramVal2 - // for NTRANS is productName, which isn't all numeric. Trouble...? - // try { - // int ok = Integer.parseInt(paramVal2); - // } catch (NumberFormatException e ) { - // paramVal2 = "0"; - // } - - String subtypeGenParam = subTypeGenParams[0]; - paramsMap.put( subTypeGenParams[0], paramVal1 ); - paramsMap.put( subTypeGenParams[1], paramVal2 ); - } - } - - return paramsMap; - } - - // - public static HashMap readAttrSetFile( File asFile ) throws VizException { - // parse the attrset file to get the attrs to substitude into the - // Bundle Template file. - HashMap< String, String > rscAttrMap = new HashMap(); - - if( asFile.length() == 0 ) { - return rscAttrMap; - } - - try { - FileReader freader = new FileReader( asFile ); - BufferedReader breader = new BufferedReader( freader ); - String prmStr = breader.readLine().trim(); - - while( prmStr != null ) { - if( prmStr.isEmpty() || prmStr.charAt(0) == '!' ) { // comments - prmStr = breader.readLine(); - continue; - } - - int eq_indx = prmStr.indexOf('='); - if( eq_indx == -1 ) { - throw new VizException("The resource prm file, "+ - asFile.getName()+", has a non-comment line with no '='"); - //prmStr = breader.readLine(); // uncomment if this is not considered a fatal error. - //continue; - } - else { - String prmKey = prmStr.substring(0,eq_indx).trim(); - String prmVal = prmStr.substring(eq_indx+1).trim(); - -// if( prmKey.equals("SKIP" ) ) { -// out.println("SKIP"); -// } - // '@' used to be a reference to a file in the same directory but with - // the localization, and since this is only used for colorbars, - // - if( !prmVal.isEmpty() && prmVal.charAt(0) == '@' ) { - try { - String refdLclName = NcPathConstants.NCEP_ROOT+prmVal.substring(1); - - if( !refdParamFilesMap.containsKey( refdLclName ) ) { - throw new VizException("Error reading file: "+asFile.getAbsolutePath() + - " : Unable to find file for parameter reference " +prmVal+"'." ); - } - File lFile = refdParamFilesMap.get( refdLclName ).getFile( true ); - - if( !lFile.exists() ) { - throw new VizException("Error reading file: "+asFile.getAbsolutePath() + - " : File for parameter reference " +prmVal+"' doesn't exist." ); - } - - FileReader fr = new FileReader(lFile); - char[] b = new char[(int) lFile.length()]; - fr.read(b); - fr.close(); - - prmVal = new String(b).trim(); - // remove the xml header - if( prmVal.startsWith("") != -1 ) { - prmVal = prmVal.substring( - prmVal.indexOf("?>")+2 ).trim(); - } - } - } catch (FileNotFoundException fnf ) { - throw new VizException( fnf ); - } catch (IOException ioe ) { - throw new VizException( ioe ); - } catch (LocalizationException lex ) { - throw new VizException( lex ); - } - } - - rscAttrMap.put( prmKey.trim(), prmVal.trim() ); - } - prmStr = breader.readLine(); - } - } catch (FileNotFoundException fnf ) { - throw new VizException( "Can't find referenced file: "+asFile.getAbsolutePath() ); - } catch (IOException fnf ) { - throw new VizException( "Can't open referenced file: "+asFile.getAbsolutePath() ); - } - - return rscAttrMap; - } - - // sort with the Obs types first and then the Fcst, and then alphabetically - public Comparator getDefaultRscDefnComparator() { - - return new Comparator() { - @Override - public int compare(ResourceDefinition rscDefn1, ResourceDefinition rscDefn2) { - - if( rscDefn1 == null ) return 1; - if( rscDefn2 == null ) return -1; - - // categories will be the same for the types but we may want to order them differently - // based on the category - // - // for Surf or UAIR, Obs before Fcst - if( rscDefn1.getResourceCategory() == ResourceCategory.SurfaceRscCategory || - rscDefn1.getResourceCategory() == ResourceCategory.UpperAirRscCategory ) { - - if( (!rscDefn1.isForecast() && rscDefn2.isForecast() ) || - (rscDefn1.isForecast() && !rscDefn2.isForecast() ) ) { - - return ( rscDefn1.isForecast() ? 1 : -1); - } - } - // for Radar, Mosaics before Local Radar - else if( rscDefn1.getResourceCategory() == ResourceCategory.RadarRscCategory ) { - if( rscDefn1.getRscImplementation().equals("RadarMosaic") ) { - return -1; - } - else if( rscDefn2.getRscImplementation().equals("RadarMosaic") ) { - return 1; - } - } - - return rscDefn1.getResourceDefnName().compareToIgnoreCase( - rscDefn2.getResourceDefnName() ); - } - }; - } - - public void setResourceEnable( String rscType, Boolean enabled ) { - ResourceDefinitionFilter rdFilt = getResourceDefnFilter( rscType ); - if( rdFilt.getIsEnabled() != enabled ) { - rdFilt.setIsEnabled( enabled ); - setResourceDefnFilters( rdFilt ); - } - } - - public void setResourceDefnFilters( ResourceDefinitionFilter rdFilt ) { - String rscType = rdFilt.getRscDefnName(); - - synchronized ( rscFiltersMap ) { - if( !rscFiltersMap.containsKey( rscType ) ) { - rscFiltersMap.put( rscType, - new TreeMap( - LocalizationLevel.REVERSE_COMPARATOR ) ); - } - - // get the highest priority filters. (stored in reverse order) - TreeMap filtMap = rscFiltersMap.get( rscType ); - filtMap.put( LocalizationLevel.USER, rdFilt ); - -// if( !filtMap.containsKey( LocalizationLevel.USER ) ) { -// ResourceDefinitionFilter curRdf = getResourceDefnFilter( rscType ); -// Boolean isEnabled = curRdf.getIsEnabled(); -// -// filtMap.put( LocalizationLevel.USER, rdFilt ); -// } -// else { -// ResourceDefinitionFilter rdFilt = filtMap.get( LocalizationLevel.USER ); -// -// rdFilt.setFilters( new ArrayList( filtList ) ); -// } - } - } - - // Don't return null. If there is no entry then create one - public ResourceDefinitionFilter getResourceDefnFilter( String rscType ) { - - if( !rscFiltersMap.containsKey( rscType ) || - rscFiltersMap.get( rscType ).keySet().isEmpty() ) { - // should we add and entry in the map here? - return new ResourceDefinitionFilter( rscType, false, null, LocalizationLevel.USER ); - } - - // get the highest priority filters. (stored in reverse order) - TreeMap filtMap = rscFiltersMap.get( rscType ); - Iterator iter = filtMap.keySet().iterator(); - LocalizationLevel llvl = (LocalizationLevel)iter.next(); -// if( iter.hasNext() ) { -// System.out.println("iterator has multiple entries and first was: "+llvl.name() ); -// } - ResourceDefinitionFilter rdFilters = filtMap.get( llvl ); - return rdFilters; - } - - // loop thru all the rsc defns for this cat and return a list of all - // filter labels. - public List getAllFilterLabelsForCategory( ResourceCategory rscCat, NcDisplayType dispType ) { - //getResourceDefnsForCategory - - ArrayList filterLabelsList = new ArrayList(); - - List rdList; - try { - rdList = getResourceDefnsForCategory(rscCat, "", dispType, false, false ); - - for( ResourceDefinition rd : rdList ) { - ResourceDefinitionFilter rdFilt = getResourceDefnFilter( rd.getResourceDefnName() ); - - for( String filtStr : rdFilt.getFilters() ) { - if( !filterLabelsList.contains( filtStr ) ) { - filterLabelsList.add( filtStr ); - } - } - } - } catch (VizException e) { - } - - return filterLabelsList; - } - - public List getResourceDefnsForCategory( ResourceCategory rscCat ) throws VizException { - return getResourceDefnsForCategory(rscCat, "", null, false, true ); + for (String rmRd : errRdsList) { + resourceDefnsMap.remove(rmRd); + } } - public List getResourceDefnsForCategory( - ResourceCategory rscCat, String filterStr, - NcDisplayType dispType, - Boolean includeGeneratedTypes, - Boolean includeDisabledRscDefns ) throws VizException { - List resourceDefnsList = new ArrayList(); - - // for other resources, get all of the resources in the given category. - // - for( ResourceDefinition rscDefn : resourceDefnsMap.values() ) { + private void readResourceDefn(LocalizationFile lFile) throws VizException { - if( !includeDisabledRscDefns && !rscDefn.isEnabled() ) { - continue; - } - - if( filterStr == null || filterStr.isEmpty() || - getResourceDefnFilter( rscDefn.getResourceDefnName() ).testFilter( filterStr ) ) { - - if( rscDefn.getResourceCategory().equals( rscCat ) ) { - if( rscDefn.getRscTypeGenerator().isEmpty() ) { - resourceDefnsList.add( rscDefn ); - } - - if( includeGeneratedTypes ) { - // TODO : could(should?) generate these from ResourceDefinition - for( String genType : rscDefn.getGeneratedTypesList() ) { - ResourceDefinition genRscDefn = new ResourceDefinition( rscDefn ); - genRscDefn.setResourceDefnName( genType ); - resourceDefnsList.add( genRscDefn ); - } - } - else if( !rscDefn.getRscTypeGenerator().isEmpty() ) { - resourceDefnsList.add( rscDefn ); - } - } -// List rscCatList = rscDefn.getRscCategories(); -// if( rscCatList.contains( rscCat ) ) { -// resourceTypes.add(rscDefn.getResourceDefnName() ); -// } - } - } - return resourceDefnsList; - //ResourceDefinition typesArray[] = resourceDefnsList.toArray( new ResourceDefinition[0] ); - -// return Arrays.asList( typesArray ); + File rscDefnFile = lFile.getFile(); + + try { + ResourceDefinition rscDefn = SerializationUtil + .jaxbUnmarshalFromXmlFile(ResourceDefinition.class, + rscDefnFile.getAbsolutePath()); + + // TODO : If the definitions are modified and written out, this will + // drop any invalid resourceDefns. + // Should we save these write them out anyway? Make them disabled? + + // Validate that the resource implementation is present and that the + // parameters are defined + // + String rscImpl = rscDefn.getRscImplementation(); + + if (!ResourceExtPointMngr.getInstance().getAvailResources() + .contains(rscImpl)) { + throw new VizException("The Resource implementation: " + + rscImpl + " for " + rscDefn.getResourceDefnName() + + " is not " + + "specified in a NC-Resource extention point"); + } else { + rscDefn.validateResourceParameters(); + + if (resourceDefnsMap.containsKey(rscDefn.getResourceDefnName())) { + throw new VizException( + "Failed to create Rsc Defn '" + + rscDefn.getResourceDefnName() + + "' from file: " + + rscDefnFile.getAbsolutePath() + + " because there is another Rsc Defn with this name."); + } + + if (rscDefn.isRequestable()) { + if (rscDefn.getPluginName() == null) { + throw new VizException( + "Failed to create Rsc Defn " + + rscDefn.getResourceDefnName() + + ": Requestable Resource is missing required pluginName parameter"); + } + + if (!RecordFactory.getInstance().getSupportedPlugins() + .contains(rscDefn.getPluginName())) { + rscDefnsWarningsList.add(new VizException("Disabling " + + rscDefn.getResourceDefnName() + + " because plugin, " + rscDefn.getPluginName() + + " is not activated.")); + } + } + + resourceDefnsMap.put(rscDefn.getResourceDefnName(), rscDefn); + + if (rscImpl.equals("Locator")) { + locatorRscDefn = rscDefn; + } + + // TODO : Change this to set the LocalizationFile or the context + rscDefn.setLocalizationFile(lFile); + + // if( rscDefn.usesInventory() ) { + // + // NcInventoryDefinition invDefn = + // rscDefn.createNcInventoryDefinition(); + // + // // throws exception on error creating a defn + // if( invDefnsMap.containsKey( invDefn ) ) { + // + // rscDefn.setInventoryAlias( + // invDefnsMap.get( invDefn ).getInventoryName() ); + // } + // } + } + } catch (SerializationException e) { + throw new VizException("Error parsing " + + rscDefnFile.getAbsolutePath() + " - " + e.getMessage()); + } catch (Exception e) { + throw new VizException("Error parsing " + + rscDefnFile.getAbsolutePath() + " - " + e.getMessage()); + } } - // if these resource type uses attributeSetGroups then return the specified - // attrSetGroups, if not then look for groups which are 'sub-types' which are - // given as - public String[] getResourceSubTypes( String rscType ) throws VizException { + private void readRefParamFiles() { + refdParamFilesMap = new HashMap(); - ResourceDefinition rscDefn = getResourceDefinition( rscType ); + // This will find all .xml (must be AttrSetGroup xml files) for all + // of the Resource implementations. + // - if( rscDefn == null ) { - return new String[0]; - } - - // generate the subTypes - return rscDefn.generatedSubTypesList().toArray( new String[0] ); + for (String refDir : refdParamDirectories) { + + Map lclFiles = pathMngr.listFiles(refDir, + new String[] { ".xml" }, true, false); + + if (lclFiles.isEmpty()) { + out.println("Error finding Files in " + refDir + + " for parameter references?"); + continue; + } + + // + for (LocalizationFile lclFile : lclFiles.values()) { + + // get the resource implementation from the path. + // String lName = lclFile.getName(); + // lName = lName.substring( NcPathConstants.NCEP_ROOT.length() + // ); + // cbarName = cbarName.substring( 0, + // cbarName.length()-".xml".length() ); + + lclFile.addFileUpdatedObserver(new ILocalizationFileObserver() { + @Override + public void fileUpdated(FileUpdatedMessage fumsg) { + String fName = fumsg.getFileName(); + LocalizationFile lFile; + + // if the file had been deleted + if (fumsg.getChangeType() == FileChangeType.DELETED) { + refdParamFilesMap.remove(fName); + // if reverted. (ie DELETED and there is a lower + // level file available) + lFile = pathMngr.getStaticLocalizationFile(fumsg + .getFileName()); + } else { + // get the ADDED, UPDATED file + lFile = pathMngr.getLocalizationFile( + fumsg.getContext(), fumsg.getFileName()); + } + + // update the map with the new file + if (lFile != null) { + refdParamFilesMap.put(fName, lFile); + } + } + }); + + if (!lclFile.isDirectory()) { + // TODO : should we unmarsh here to validate? + // + refdParamFilesMap.put(lclFile.getName(), lclFile); + } + // else { + // out.println("Adding observer to LFile "+lclFile.getContext()+":"+lclFile.getName() + // ); + // } + } + } + } + + // initialize the attrSetMap and the attrSetGroupsMap + // + private void readAttrSets() throws VizException { + + attrSetGroupsMap = new HashMap(); + + // This will find all .xml (must be AttrSetGroup xml files) for all + // of the Resource implementations. + // + Map attrSetGrpLclFiles = pathMngr.listFiles( + NcPathConstants.ATTR_SET_GROUPS_DIR, new String[] { ".xml" }, + true, true); + + if (attrSetGrpLclFiles.isEmpty()) { + out.println("Error finding AttrSetGroup Files?"); + return; + } + + // the sub-dirs under the attrSetGroups dir must match a + // resourceImplClass + // + // check that the naming convention is used. If not then there can be a + // potential problem if the + // group is edited since it will be given a different localization Name. + + for (LocalizationFile lclFile : attrSetGrpLclFiles.values()) { + + // TODO : add localization observer to update the Map when a + // localization file has + // changed on another cave. + + File asgFile = lclFile.getFile(); + + if (!asgFile.exists()) { + out.println("Can't open AttrSetGroup file: " + + asgFile.getAbsolutePath()); + continue; + } + AttrSetGroup asg; + try { + asg = SerializationUtil.jaxbUnmarshalFromXmlFile( + AttrSetGroup.class, asgFile.getAbsolutePath()); + + } catch (SerializationException e) { + throw new VizException("Error Parsing file " + + asgFile.getAbsolutePath() + "\n" + e.getMessage()); + } + + // add the ASG's in the list to the map. (PGEN is a special case + // since + // 1 'default' ASG applies to all PGEN resources.) + asg.setLocalizationFile(lclFile); + + // if not PGEN then + // validate that there is a resourceImpl for this attrSetGroup + // + if (!asg.getRscAndGroupName().isPGEN()) { + + ResourceDefinition asgRscDefn = getResourceDefinition(asg + .getResource()); + if (asgRscDefn == null) { + out.println("AttrSetGroup file " + asgFile.getName() + + " has a unknown resource:" + asg.getResource()); + continue; + } + + String rscImpl = asgRscDefn.getRscImplementation(); + + if (!ResourceExtPointMngr.getInstance().getAvailResources() + .contains(rscImpl)) { + out.println("Can't find Resource Implementation (class) for " + + "attrSetGroup : " + rscImpl); + + out.println("The Resource implementation should be specified in " + + "a NC-Resource extention point"); + // don't fail; go ahead and put the attrset in the map + } + + // check that the file name follows the convention otherwise + // there could be a + // problem if the user edits it since the name for the + // USER-level file will be + // different and not recognized as the same group. + // + String lFileName = NcPathConstants.ATTR_SET_GROUPS_DIR + + File.separator + rscImpl + File.separator + + asg.getResource() + "-" + asg.getAttrSetGroupName() + + ".xml"; + + if (!lFileName.equals(lclFile.getName())) { + out.println("Warning: Localization file for AttrSetGroup, " + + lclFile.getName() + + " doesn't follow the naming convention.(" + + lFileName + ")"); + } + } + + if (attrSetGroupsMap.containsKey(asg.getRscAndGroupName() + .toString())) { + System.out.println(asg.getRscAndGroupName().toString() + + " already in the map???"); + + } + + // + attrSetGroupsMap.put(asg.getRscAndGroupName().toString(), asg); + } + + // Next set the attrSetMap. + + // This is a map from the resource type or rsc impl to a map of the + // available attribute sets + attrSetMap = new HashMap>(); + + // first get the attrSets for the AttrSetGroups. + // In this case the key is the resource Implementation instead of the + // resource type + // + Map attrSetLclFiles = pathMngr.listFiles( + NcPathConstants.ATTR_SET_GROUPS_DIR, + new String[] { ATTR_SET_FILE_EXT }, true, true); + + if (attrSetLclFiles.isEmpty()) { + out.println("Error finding AttrSets (for AttrSetGroups) Files?"); + return; + } + + // the sub-dirs under attrSetGroups must match a resourceImplClass + // + for (LocalizationFile asLclFile : attrSetLclFiles.values()) { + + // get the resource implementation from the path. + // String asLclName = asLclFile.getName().substring( + // ATTR_SET_GROUPS_DIR.length()+1 ); + // String rscImpl = asLclName.substring( 0, + // asLclName.indexOf( File.separator ) ); + // String attrSetName = asLclName.substring(rscImpl.length()+1, + // asLclName.length()-ATTR_SET_FILE_EXT.length() ); + String rscImpl = asLclFile.getFile().getParentFile().getName(); + // String attrSetName = asLclFile.getFile().getName(); + // attrSetName = attrSetName.substring(0, + // attrSetName.length()-ATTR_SET_FILE_EXT.length() ); + // ArrayList rscTypes = getRscTypesForRscImplementation( + // rscImpl ); + + if (!attrSetMap.containsKey(rscImpl)) { + attrSetMap.put(rscImpl, new HashMap()); + } + try { + AttributeSet aSet = AttributeSet.createAttributeSet(rscImpl, + asLclFile); + + attrSetMap.get(rscImpl).put(aSet.getName(), aSet); + } catch (VizException e) { + out.println("Error Creating AttributeSet " + + asLclFile.getName() + ": " + e.getMessage()); + } + } + + // Next get the attrSets for other resources which have attribute sets + // of their own. + // In this case the key is the resource type name. + // + attrSetLclFiles = pathMngr.listFiles(NcPathConstants.RSC_DEFNS_DIR, + new String[] { ATTR_SET_FILE_EXT }, true, true); + + if (attrSetLclFiles.isEmpty()) { + out.println("Error finding AttrSet Files?"); + return; + } + + for (LocalizationFile asLclFile : attrSetLclFiles.values()) { + + // if( asLclFile.getContext().getLocalizationLevel() == + // LocalizationLevel.USER ) { + // out.println(" USER"); + // } + // Some resources may have more organizational directories than + // others. The resource + // type is the lowest directory. + String dirs[] = asLclFile.getName().split(File.separator); + if (dirs == null || dirs.length < 3) { + continue; // ????? + } + + // String attrSetName = dirs[ dirs.length-1 ]; + // attrSetName = attrSetName.substring( 0, + // attrSetName.length()-ATTR_SET_FILE_EXT.length() ); + + String rscType = dirs[dirs.length - 2]; + + if (!attrSetMap.containsKey(rscType)) { + attrSetMap.put(rscType, new HashMap()); + } + + try { + AttributeSet aSet = AttributeSet.createAttributeSet(rscType, + asLclFile); + + attrSetMap.get(rscType).put(aSet.getName(), aSet); + } catch (VizException e) { + out.println("Error Creating AttributeSet " + + asLclFile.getName() + ": " + e.getMessage()); + } + } + + // validate that the attrSets referenced from the attrSetGroups actually + // exist + // (PGEN is a special case) + for (AttrSetGroup asg : attrSetGroupsMap.values()) { + + String rscType = asg.getResource(); + String attrSetMapKey = ""; + + if (asg.getRscAndGroupName().isPGEN()) { + attrSetMapKey = asg.getResource(); + } else { + ResourceDefinition rscDefn = getResourceDefinition(rscType); + if (rscDefn != null) { + attrSetMapKey = rscDefn.getRscImplementation(); + } + } + + for (String asName : new ArrayList(asg.getAttrSetNames())) { + if (!attrSetMap.containsKey(attrSetMapKey) + || !attrSetMap.get(attrSetMapKey).containsKey(asName)) { + + asg.removeAttrSet(asName); + out.println("attrSet " + asName + " in attrSetGroup " + + asg.getResource() + File.separator + + asg.getAttrSetGroupName() + " doesn't exist."); + } + } + } + } + + public List findOrCreateInventoryForRscDefns( + Collection rscDefnsToSetup) { + // loop thru the ResourceDefns and enable those that have been + // initialized and + // find any inventories that don't exist and create them + // + // This would read the inventoryDefns from localizations (ie what edex + // uses) + // to initialize but instead we will query edex to see what's there and + // only create inventories that don't exist. + // checkAndSaveNcInventories(); + Map invDefnsMap = null; + + // its possible this is failing/empty on the testbed for some unknown + // reason. Since this will cause 'duplicate' ID to be created we should + // retry to make sure. + for (int tryCount = 1; tryCount <= 5; tryCount++) { + try { + invDefnsMap = getInventoryDefinitions(); + + if (invDefnsMap == null || invDefnsMap.isEmpty()) { + throw new VizException("Inventory Directory is Empty?"); + } else { + break; + } + } catch (VizException ve) { + System.out.println("Error getting NcInventory Directory" + + ve.getMessage()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + } + + if (invDefnsMap == null) { + invDefnsMap = new HashMap(); + } + + List createInvDefns = new ArrayList(); + List errList = new ArrayList(); + + for (ResourceDefinition rd : rscDefnsToSetup) { + try { + HashMap rc = rd + .getInventoryConstraintsFromParameters(rd + .getResourceParameters(true)); + List reqParams = rd.getUnconstrainedParameters(); + reqParams.add("dataTime"); + + for (NcInventoryDefinition edexID : invDefnsMap.keySet()) { + if (edexID.supportsQuery(rc, reqParams)) { + if (rd.isInventoryInitialized()) { + System.out.println("RD " + rd.getResourceDefnName() + + " has more than one supporting ID, " + + rd.getInventoryAlias() + " and " + + edexID.getInventoryName()); + } + System.out.println("Inventory found for " + + rd.getResourceDefnName() + " is " + + edexID.getInventoryName()); + rd.setInventoryAlias(edexID.getInventoryName()); + // break; + } + } + + if (rd.usesInventory() && rd.getInventoryEnabled() + && !rd.isInventoryInitialized()) { + + createInvDefns.add(rd.createNcInventoryDefinition()); + } + } catch (VizException e) { + out.println("Error creating ResourceDefn from file: " + + rd.getLocalizationFile().getName()); + out.println(" --->" + e.getMessage()); + badRscDefnsList.add(e); + } + } + + if (!createInvDefns.isEmpty()) { + InventoryLoaderJob invLoader = new InventoryLoaderJob( + createInvDefns, false); + + invLoader.schedule(); + + // TODO : update the progress monitor + while (invLoader.getNumberOfInventoriesLeftToLoad() > 0) { + // out.println("Inventories left to load = "+invLoader.getNumberOfInventoriesLeftToLoad() + // ); + try { + Thread.sleep(400); + } catch (InterruptedException e) { + } + } + + errList = Arrays.asList(invLoader.getUninitializedInventoryDefns()); + } + + List errRdsList = new ArrayList(); + + // for the rscDefns that just had an inventory created for them + // enable or disable based on whether there was an error. + // + for (ResourceDefinition rd : resourceDefnsMap.values()) { + + if (rd.usesInventory()) { + try { + NcInventoryDefinition invDefn = rd + .createNcInventoryDefinition(); + + // if created successfully set the inventoryName/Alias + if (createInvDefns.contains(invDefn) + && !errList.contains(invDefn)) { + + rd.setInventoryAlias(invDefn.getInventoryName()); + } + + // if there is an inventory and if it is enabled + if (rd.getInventoryEnabled() && !errList.contains(invDefn)) { + + rd.enableInventoryUse(); // remove the + // ProductAlertObserver + } else { + rd.disableInventoryUse(); // add the + // ProductAlertObserver and + // query types/subTypes + } + } catch (VizException e) { + // rd.setInventoryEnabled(false); + // setResourceEnable( rd.getResourceDefnName(), false ); + errRdsList.add(rd.getResourceDefnName()); + + out.println("Error creating ResourceDefn : " + + rd.getResourceDefnName()); + out.println(" --->" + e.getMessage()); + badRscDefnsList.add(new VizException( + "Error creating ResourceDefn : " + + rd.getResourceDefnName() + " : " + + e.getMessage())); + } + } + } + + return errRdsList; + } + + // a list of inventories definitions available on edex. + // used to set the inventoryInitialized flag. + public Map getInventoryDefinitions() + throws VizException { + + Map invDefnsMap = null; + + // query the list of inventories that exist on edex and set the + // inventoryInitialized flag in the ResourceDefns + NcInventoryRequestMsg dirRequest = NcInventoryRequestMsg + .makeDirectoryRequest(); + + Object rslts = ThriftClient.sendRequest(dirRequest); + + if (rslts instanceof String) { + throw new VizException(rslts.toString()); + } + if (!(rslts instanceof ArrayList)) { + throw new VizException( + "Inventory Directory Request Error: expecting ArrayList."); + } else if (((ArrayList) rslts).isEmpty()) { + out.println("Inventory Directory Request Warning: No Inventories initialized.???"); + } else if (!(((ArrayList) rslts).get(0) instanceof NcInventoryDefinition)) { + throw new VizException( + "Inventory Directory Request Error: expecting ArrayList."); + } + + // used to set the inventory initialized flag + ArrayList invDefnsList = (ArrayList) rslts; + + invDefnsMap = new HashMap(); + + for (NcInventoryDefinition invDefn : invDefnsList) { + invDefnsMap.put(invDefn, invDefn); + } + + return invDefnsMap; + } + + public boolean isResourceNameValid(ResourceName rscName) { + if (rscName == null || rscName.getRscCategory() == null + || rscName.getRscCategory() == ResourceCategory.NullCategory + || rscName.getRscType() == null + || rscName.getRscType().isEmpty() + || rscName.getRscAttrSetName() == null + || rscName.getRscAttrSetName().isEmpty()) { + + return false; + } + + ResourceDefinition rd = getResourceDefinition(rscName); + + if (rd == null) { + return false; + } + + // if there is a generating type then check for a ':' + // + if (!rd.getRscTypeGenerator().isEmpty()) { + if (rscName.getRscType().indexOf( + ResourceName.generatedTypeDelimiter) == -1) { + // out.println("ResourceName "+rscName.toString() + + // " is expecting a "+ + // "generated type from the "+ rd.getRscTypeGenerator() ); + return false; + } + } + // if there is no group/subType, make sure there isn't supposed to be + // one. + if (rscName.getRscGroup() == null || rscName.getRscGroup().isEmpty()) { + + if (rd.applyAttrSetGroups() || !rd.getSubTypeGenerator().isEmpty()) { + // out.println("ResourceName "+rscName.toString() + + // " is expecting a "+ + // "generated sub-type from "+ rd.getSubTypeGenerator() ); + return false; + } + } else { // and if there is one + + } + + return true; + } + + // similar to validateResourceParameters except we are also checking for the + // attributes + // public void verifyParametersExist( ResourceName rscName ) throws + // VizException { + // ResourceDefinition rscDefn = getResourceDefinition( rscName.getRscType() + // ); + // + // if( rscDefn == null ) { + // throw new + // VizException("Unable to find resource definition for "+rscName.toString() + // ); + // } + // + // rscDefn.validateResourceParameters(); + // + // HashMap rscImplParams = + // ResourceExtPointMngr.getInstance().getResourceParameters( + // rscDefn.getRscImplementation() ); + // + // // the default values specified in the extention point + // HashMap dfltParamValues = + // rscDefn.getDefaultParameterValues(); + // + // // the parameters defined by the resource definition + // HashMap paramValues = getAllResourceParameters( rscName ); + // + // // a list of all the generated parameters + // List genParamsList = new ArrayList( Arrays.asList( + // rscDefn.getSubTypeGenParamsList() ) ); + // if( !rscDefn.getRscTypeGenerator().isEmpty() ) { + // genParamsList.add( rscDefn.getRscTypeGenerator() ); + // } + // + // // check that all the parameters defined for the implmentation either + // have a + // // value given in the rsc params, will be generated, or have a default + // value + // // + // for( ResourceParamInfo implPrmInfo : rscImplParams.values() ) { + // String implPrm = implPrmInfo.getParamName(); + // String prmConstraintName = implPrmInfo.getConstraintName();// same as + // paramName except for GDFILE and 1 or 2 others. + // + // if( implPrmInfo.getParamType() == ResourceParamType.EDITABLE_ATTRIBUTE || + // implPrmInfo.getParamType() == ResourceParamType.NON_EDITABLE_ATTRIBUTE ) + // { + // + // // if the needed param is not set in the resource defn or is set to empty + // String paramValue = paramValues.get( implPrm ); + // + // if( paramValue == null || paramValue.isEmpty() ) { + // + // paramValue = dfltParamValues.get( implPrm ); + // + // // if there is no default value specified by the implementation + // // + // if( paramValue == null || paramValue.isEmpty() ) { + // throw new VizException( rscDefn.getResourceDefnName()+ + // " is missing a value for the attribute "+implPrm+"." ); + // } + // else { + // out.println("Setting attribute "+implPrm+" to default value "+paramValue + // ); + // } + // } + // } + // + // // if this is not a generated request constraint, then check the + // inventory to make + // // sure that this value is in the database + // // + // else if( implPrmInfo.getParamType() == + // ResourceParamType.REQUEST_CONSTRAINT ) { + // // if there is not a value for this parameter + // // + // if( !paramValues.containsKey( implPrm ) ) { + // throw new VizException( + // "The parameter "+implPrm+" is not available for resource "+ + // rscDefn.getResourceDefnName()+"." ); + // } + // + // // if this parameter is in the inventory then see if we need to + // // see if the value (given in the selected attrSet) is in the inventory. + // // + // if( rscDefn.getInventoryParameterNames().contains( prmConstraintName ) ) + // { + // + // // if this is not a generated parameter + // // (assume that since it was generated then it must be in the inventory, + // // currently this is true but may not be if this method is ever + // // called from other than updateSelectedResource.) + // // + // if( !genParamsList.contains( prmConstraintName ) ) { + // + // ArrayList qRslts = rscDefn.queryInventoryParameter( rscName, + // prmConstraintName ); + // + // if( qRslts.isEmpty() ) { + // throw new VizException( + // "The parameter value "+implPrm+"="+paramValues.get(implPrm)+ + // " is not available for resource "+ rscDefn.getResourceDefnName()+"." ); + // } + // + // out.println("Inventory has "+ qRslts.size() +" values"); + // } + // } + // } + // } + // + // // check that all of the paramValues are specified for the rsc + // implementation + // // + // for( String prm : paramValues.keySet() ) { + // if( !prm.equals("pluginName") && + // !paramInfoForRscDefnParamsMap.containsKey( prm ) && + // !rscImplParams.containsKey( prm ) ) { + // + // // out.println("Warning: parameter "+prm+" for "+getResourceDefnName()+ + // // + // " is not recognized for the resource implementation "+getRscImplementation() + // ); + // + // throw new VizException( + // rscDefn.getResourceDefnName()+" has a parameter, "+prm+ + // ", that is not recognized by its implementation: "+ + // rscDefn.getRscImplementation() ); + // } + // } + // } + + public ResourceDefinition getResourceDefinition(ResourceName rscName) { + return (rscName != null ? getResourceDefinition(rscName.getRscType()) + : null); + } + + public boolean findResourceDefinition(String rscType) { + if (resourceDefnsMap.containsKey(rscType)) { + return true; + } + + // allow for generated types which will have a ':' + // + int indx = rscType.indexOf(":"); + + if (indx == -1) { + return false; + } + + return resourceDefnsMap.containsKey(rscType.substring(0, indx)); + } + + public ResourceDefinition getResourceDefinition(String rscType) { + if (resourceDefnsMap.containsKey(rscType)) { + return resourceDefnsMap.get(rscType); + } + + // allow for generated types which will have a ':' + // + int indx = rscType.indexOf(":"); + + if (indx != -1) { + if (resourceDefnsMap.containsKey(rscType.substring(0, indx))) { + return resourceDefnsMap.get(rscType.substring(0, indx)); + } + } + + // out.println("sanity check: can't find ResourceDefinition for: "+rscType + // ); + return null; + } + + // defined as an array but for now only assume 1 disp type in the list. + public ResourceCategory[] getResourceCategories(boolean includeDisabled, + NcDisplayType[] matchingDispTypes) { + + if (matchingDispTypes.length != 1) { + System.out + .println("getResourceCategories called with more than one display type. Only matching the first one"); + } + + ArrayList catsList = new ArrayList(); + + // loop thru all the available categories in order and if a resource + // defn + // exists for it then + for (ResourceCategory rc : ResourceCategory.values()) { + + for (ResourceDefinition rscDefn : resourceDefnsMap.values()) { + + if (rc == rscDefn.getResourceCategory()) { + + if (includeDisabled || rscDefn.isEnabled()) { + + if (rscDefn + .isDisplayTypeSupported(matchingDispTypes[0])) { + + if (!catsList.contains(rc)) { + catsList.add(rc); + break; + } + } + } + } + } + } + + ResourceCategory[] catsArray = catsList + .toArray(new ResourceCategory[0]); + // + // Arrays.sort( catsArray, new Comparator() { + // public int compare(String o1, String o2) { + // int indx1 = availResourceCategoriesList.indexOf( (String)o1 ); + // int indx2 = availResourceCategoriesList.indexOf( (String)o2 ); + // + // return ((indx1 == indx2 ? 0 : (indx1 < indx2 ? -1 : 1 ))); + // } + // }); + + return catsArray; + + // return catsList.toArray( new String[0] ); + // return ResourceCategories; + } + + // map the Full Resource Name to the location of the resource bundle + // template file + // for the resource. + // The rsc name is the RBD Category/Type/Group/AttributeSet. The fcst/obs is + // not saved + // so we try both to find a match. + public File getRscBundleTemplateFile(String rscType) { + ResourceDefinition rscDefn = getResourceDefinition(rscType); + + if (rscDefn == null) { + return null; + } + + // get the name of the NC resource which will implement the resource + String rscImplName = rscDefn.getRscImplementation(); + + if (!rscImplName.endsWith(".xml")) { + rscImplName = rscImplName + ".xml"; + } + File rscTemplateFile = pathMngr + .getStaticFile(NcPathConstants.RSC_TMPLTS_DIR + File.separator + + rscImplName); + + return (rscTemplateFile.exists() ? rscTemplateFile : null); + } + + // + public boolean doesResourceUseAttrSetGroups(String rscType) { + ResourceDefinition rscDefn = getResourceDefinition(rscType); + + return (rscDefn == null ? false : rscDefn.applyAttrSetGroups()); + } + + // + // + public String getDefaultFrameTimesSelections(ResourceName rscName) + throws VizException { + ResourceDefinition rscDefn = getResourceDefinition(rscName.getRscType()); + + if (rscDefn == null) { + return null; + } + + HashMap paramsMap = new HashMap( + rscDefn.getResourceParameters(false)); + + AttributeSet attrSet = getAttrSet(rscName); + + if (attrSet != null) { + paramsMap.putAll(attrSet.getAttributes()); + } + + if (paramsMap.containsKey("GDATTIM")) { + + // check syntax + new SelectableFrameTimeMatcher(paramsMap.get("GDATTIM")); + + return paramsMap.get("GDATTIM"); + } else { + return null; + } + } + + // get the Attribute Set File for the given resource name. This may either + // be in the AttrSetGroup directory or directly under the resources config + // dir. + + // Get all parameters needed to instantiate the bundle template + // This includes parameters from the ResourceDefinition, attributes and + // timeMatching/frameCount... + // + public HashMap getAllResourceParameters(ResourceName rscName) + throws VizException { + + ResourceDefinition rscDefn = getResourceDefinition(rscName.getRscType()); + + if (rscDefn == null) { + return null; + } + + // first get the parameters defined by the RscDefn and use the default + // values + // for any that are not present. + HashMap paramsMap = new HashMap( + rscDefn.getResourceParameters(true)); + + // next get the attributes + AttributeSet attrSet = getAttrSet(rscName); + + if (attrSet != null) { + paramsMap.putAll(attrSet.getAttributes()); + } + + if (paramsMap.containsKey("GDATTIM")) { + paramsMap.remove("GDATTIM"); + } + + // and now create the parameters from the rscDefinitions file. + // (frameInterval, timeMatchMethod) + if (rscDefn.getResourceCategory() != ResourceCategory.OverlayRscCategory) { + + paramsMap + .put("frameSpan", Integer.toString(rscDefn.getFrameSpan())); + paramsMap.put("timeMatchMethod", rscDefn.getTimeMatchMethod() + .toString()); + paramsMap.put("dfltNumFrames", + Integer.toString(rscDefn.getDfltFrameCount())); + // paramsMap.put("dfltGraphRange", + // Integer.toString(rscDefn.getDfltGraphRange())); + // paramsMap.put("dfltHourSnap", + // Integer.toString(rscDefn.getDfltHourSnap())); + paramsMap.put("dfltTimeRange", + Integer.toString(rscDefn.getDfltTimeRange())); + paramsMap.put("timelineGenMethod", rscDefn.getTimelineGenMethod() + .toString()); + + paramsMap.put("isForecast", (rscDefn.isForecast() ? "true" + : "false")); + } + + // if this is a generated type get the parameter value from the type in + // the ResourceName + // + String typeGenParam = rscDefn.getRscTypeGenerator(); + + if (!typeGenParam.isEmpty()) { + + String rscType = rscName.getRscType(); + int indx = rscType.indexOf(":"); + if (indx == -1) { + throw new VizException( + "sanity check: Can't parse generated typ from " + + "Resource name :" + rscName.toString()); + } + + String typeName = rscType.substring(indx + 1); + + paramsMap.put(typeGenParam, typeName); + } + + // If there is a generated sub-type then we will need to set a parameter + // for this + // (In this case the name of the parameter in the paramsMap must be the + // same as the + // name of the variable in the BundleTemplate.) + // + String[] subTypeGenParams = rscDefn.getSubTypeGenParamsList(); + + if (subTypeGenParams.length == 1) { + paramsMap.put(subTypeGenParams[0], rscName.getRscGroup()); + } + + // TODO : Note this currently only works for Satellite because its + // the only resource that uses 2 generating params, (the area and + // resolution) + // A trailing 'km' which means this parsing code is not generic + // + else if (subTypeGenParams.length == 2) { + + String subType = rscName.getRscGroup(); + // if( !subType.endsWith( "km" ) ) { + // out.println("Sanity check : SubType "+subType + // +" is expected to end with 'km'"); + // } + + int indx = subType.lastIndexOf('_'); + if (indx != -1) { + String paramVal1 = subType.substring(0, indx); + String paramVal2 = subType.endsWith("km") ? subType.substring( + indx + 1, subType.length() - 2) // NOTE; "km" + : subType.substring(indx + 1, subType.length()); + // TODO : get rid of these hacks and redesign the resoureName + // <-> parameter value mapping + if (paramVal2.equals("native")) { + paramVal2 = "0"; + } + // TODO -- Can't make following sanity-check / cleanup anymore + // because paramVal2 + // for NTRANS is productName, which isn't all numeric. + // Trouble...? + // try { + // int ok = Integer.parseInt(paramVal2); + // } catch (NumberFormatException e ) { + // paramVal2 = "0"; + // } + + String subtypeGenParam = subTypeGenParams[0]; + paramsMap.put(subTypeGenParams[0], paramVal1); + paramsMap.put(subTypeGenParams[1], paramVal2); + } + } + + return paramsMap; + } + + // + public static HashMap readAttrSetFile(File asFile) + throws VizException { + // parse the attrset file to get the attrs to substitude into the + // Bundle Template file. + HashMap rscAttrMap = new HashMap(); + + if (asFile.length() == 0) { + return rscAttrMap; + } + + try { + FileReader freader = new FileReader(asFile); + BufferedReader breader = new BufferedReader(freader); + String prmStr = breader.readLine().trim(); + + while (prmStr != null) { + if (prmStr.isEmpty() || prmStr.charAt(0) == '!') { // comments + prmStr = breader.readLine(); + continue; + } + + int eq_indx = prmStr.indexOf('='); + if (eq_indx == -1) { + throw new VizException("The resource prm file, " + + asFile.getName() + + ", has a non-comment line with no '='"); + // prmStr = breader.readLine(); // uncomment if this is not + // considered a fatal error. + // continue; + } else { + String prmKey = prmStr.substring(0, eq_indx).trim(); + String prmVal = prmStr.substring(eq_indx + 1).trim(); + + // if( prmKey.equals("SKIP" ) ) { + // out.println("SKIP"); + // } + // '@' used to be a reference to a file in the same + // directory but with + // the localization, and since this is only used for + // colorbars, + // + if (!prmVal.isEmpty() && prmVal.charAt(0) == '@') { + try { + String refdLclName = NcPathConstants.NCEP_ROOT + + prmVal.substring(1); + + if (!refdParamFilesMap.containsKey(refdLclName)) { + throw new VizException( + "Error reading file: " + + asFile.getAbsolutePath() + + " : Unable to find file for parameter reference " + + prmVal + "'."); + } + File lFile = refdParamFilesMap.get(refdLclName) + .getFile(true); + + if (!lFile.exists()) { + throw new VizException("Error reading file: " + + asFile.getAbsolutePath() + + " : File for parameter reference " + + prmVal + "' doesn't exist."); + } + + FileReader fr = new FileReader(lFile); + char[] b = new char[(int) lFile.length()]; + fr.read(b); + fr.close(); + + prmVal = new String(b).trim(); + // remove the xml header + if (prmVal.startsWith("") != -1) { + prmVal = prmVal.substring( + prmVal.indexOf("?>") + 2).trim(); + } + } + } catch (FileNotFoundException fnf) { + throw new VizException(fnf); + } catch (IOException ioe) { + throw new VizException(ioe); + } catch (LocalizationException lex) { + throw new VizException(lex); + } + } + + rscAttrMap.put(prmKey.trim(), prmVal.trim()); + } + prmStr = breader.readLine(); + } + } catch (FileNotFoundException fnf) { + throw new VizException("Can't find referenced file: " + + asFile.getAbsolutePath()); + } catch (IOException fnf) { + throw new VizException("Can't open referenced file: " + + asFile.getAbsolutePath()); + } + + return rscAttrMap; + } + + // sort with the Obs types first and then the Fcst, and then alphabetically + public Comparator getDefaultRscDefnComparator() { + + return new Comparator() { + @Override + public int compare(ResourceDefinition rscDefn1, + ResourceDefinition rscDefn2) { + + if (rscDefn1 == null) + return 1; + if (rscDefn2 == null) + return -1; + + // categories will be the same for the types but we may want to + // order them differently + // based on the category + // + // for Surf or UAIR, Obs before Fcst + if (rscDefn1.getResourceCategory() == ResourceCategory.SurfaceRscCategory + || rscDefn1.getResourceCategory() == ResourceCategory.UpperAirRscCategory) { + + if ((!rscDefn1.isForecast() && rscDefn2.isForecast()) + || (rscDefn1.isForecast() && !rscDefn2.isForecast())) { + + return (rscDefn1.isForecast() ? 1 : -1); + } + } + // for Radar, Mosaics before Local Radar + else if (rscDefn1.getResourceCategory() == ResourceCategory.RadarRscCategory) { + if (rscDefn1.getRscImplementation().equals("RadarMosaic")) { + return -1; + } else if (rscDefn2.getRscImplementation().equals( + "RadarMosaic")) { + return 1; + } + } + + return rscDefn1.getResourceDefnName().compareToIgnoreCase( + rscDefn2.getResourceDefnName()); + } + }; + } + + public void setResourceEnable(String rscType, Boolean enabled) { + ResourceDefinitionFilter rdFilt = getResourceDefnFilter(rscType); + if (rdFilt.getIsEnabled() != enabled) { + rdFilt.setIsEnabled(enabled); + setResourceDefnFilters(rdFilt); + } + } + + public void setResourceDefnFilters(ResourceDefinitionFilter rdFilt) { + String rscType = rdFilt.getRscDefnName(); + + synchronized (rscFiltersMap) { + if (!rscFiltersMap.containsKey(rscType)) { + rscFiltersMap + .put(rscType, + new TreeMap( + LocalizationLevel.REVERSE_COMPARATOR)); + } + + // get the highest priority filters. (stored in reverse order) + TreeMap filtMap = rscFiltersMap + .get(rscType); + filtMap.put(LocalizationLevel.USER, rdFilt); + + // if( !filtMap.containsKey( LocalizationLevel.USER ) ) { + // ResourceDefinitionFilter curRdf = getResourceDefnFilter( rscType + // ); + // Boolean isEnabled = curRdf.getIsEnabled(); + // + // filtMap.put( LocalizationLevel.USER, rdFilt ); + // } + // else { + // ResourceDefinitionFilter rdFilt = filtMap.get( + // LocalizationLevel.USER ); + // + // rdFilt.setFilters( new ArrayList( filtList ) ); + // } + } + } + + // Don't return null. If there is no entry then create one + public ResourceDefinitionFilter getResourceDefnFilter(String rscType) { + + if (!rscFiltersMap.containsKey(rscType) + || rscFiltersMap.get(rscType).keySet().isEmpty()) { + // should we add and entry in the map here? + return new ResourceDefinitionFilter(rscType, false, null, + LocalizationLevel.USER); + } + + // get the highest priority filters. (stored in reverse order) + TreeMap filtMap = rscFiltersMap + .get(rscType); + Iterator iter = filtMap.keySet().iterator(); + LocalizationLevel llvl = (LocalizationLevel) iter.next(); + // if( iter.hasNext() ) { + // System.out.println("iterator has multiple entries and first was: "+llvl.name() + // ); + // } + ResourceDefinitionFilter rdFilters = filtMap.get(llvl); + return rdFilters; + } + + // loop thru all the rsc defns for this cat and return a list of all + // filter labels. + public List getAllFilterLabelsForCategory(ResourceCategory rscCat, + NcDisplayType dispType) { + // getResourceDefnsForCategory + + ArrayList filterLabelsList = new ArrayList(); + + List rdList; + try { + rdList = getResourceDefnsForCategory(rscCat, "", dispType, false, + false); + + for (ResourceDefinition rd : rdList) { + ResourceDefinitionFilter rdFilt = getResourceDefnFilter(rd + .getResourceDefnName()); + + for (String filtStr : rdFilt.getFilters()) { + if (!filterLabelsList.contains(filtStr)) { + filterLabelsList.add(filtStr); + } + } + } + } catch (VizException e) { + } + + return filterLabelsList; + } + + public List getResourceDefnsForCategory( + ResourceCategory rscCat) throws VizException { + return getResourceDefnsForCategory(rscCat, "", null, false, true); + } + + public List getResourceDefnsForCategory( + ResourceCategory rscCat, String filterStr, NcDisplayType dispType, + Boolean includeGeneratedTypes, Boolean includeDisabledRscDefns) + throws VizException { + List resourceDefnsList = new ArrayList(); + + // for other resources, get all of the resources in the given category. + // + for (ResourceDefinition rscDefn : resourceDefnsMap.values()) { + + if (!includeDisabledRscDefns && !rscDefn.isEnabled()) { + continue; + } + + if (filterStr == null + || filterStr.isEmpty() + || getResourceDefnFilter(rscDefn.getResourceDefnName()) + .testFilter(filterStr)) { + + if (rscDefn.getResourceCategory().equals(rscCat)) { + if (rscDefn.getRscTypeGenerator().isEmpty()) { + resourceDefnsList.add(rscDefn); + } + + if (includeGeneratedTypes) { + // TODO : could(should?) generate these from + // ResourceDefinition + for (String genType : rscDefn.getGeneratedTypesList()) { + ResourceDefinition genRscDefn = new ResourceDefinition( + rscDefn); + genRscDefn.setResourceDefnName(genType); + resourceDefnsList.add(genRscDefn); + } + } else if (!rscDefn.getRscTypeGenerator().isEmpty()) { + resourceDefnsList.add(rscDefn); + } + } + // List rscCatList = rscDefn.getRscCategories(); + // if( rscCatList.contains( rscCat ) ) { + // resourceTypes.add(rscDefn.getResourceDefnName() ); + // } + } + } + return resourceDefnsList; + // ResourceDefinition typesArray[] = resourceDefnsList.toArray( new + // ResourceDefinition[0] ); + + // return Arrays.asList( typesArray ); + } + + // if these resource type uses attributeSetGroups then return the specified + // attrSetGroups, if not then look for groups which are 'sub-types' which + // are + // given as + public String[] getResourceSubTypes(String rscType) throws VizException { + + ResourceDefinition rscDefn = getResourceDefinition(rscType); + + if (rscDefn == null) { + return new String[0]; + } + + // generate the subTypes + return rscDefn.generatedSubTypesList().toArray(new String[0]); } // look up using a resource name - public AttrSetGroup getAttrSetGroupForResource( ResourceName rscName) { - ResourceDefinition rscDefn = getResourceDefinition( rscName ); - if( rscDefn == null ) { - return null; - } - return getAttrSetGroupForResource( - new RscAndGroupName( rscDefn.getResourceDefnName(), rscName.getRscGroup() ) ); + public AttrSetGroup getAttrSetGroupForResource(ResourceName rscName) { + ResourceDefinition rscDefn = getResourceDefinition(rscName); + if (rscDefn == null) { + return null; + } + return getAttrSetGroupForResource(new RscAndGroupName( + rscDefn.getResourceDefnName(), rscName.getRscGroup())); } - + // lookup usging the rscType and the asg name - public AttrSetGroup getAttrSetGroupForResource(RscAndGroupName attrSetGroupName ) { - return attrSetGroupsMap.get( attrSetGroupName.toString() ); + public AttrSetGroup getAttrSetGroupForResource( + RscAndGroupName attrSetGroupName) { + return attrSetGroupsMap.get(attrSetGroupName.toString()); } - - + // this is all of the attribute set groups available for a resource // (the returned list references the actual AttrSetGroup objects) // - public ArrayList getAttrSetGroupsForResource( String rscType ) { - // loop thru all the entries in the attrSetGroupsMap and return those - // that match the rscImpl - ArrayList attrSetGroupsList = new ArrayList(); - - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - - if( rscDefn== null ) { - return attrSetGroupsList; - } - else { - for( AttrSetGroup asg : attrSetGroupsMap.values() ) { + public ArrayList getAttrSetGroupsForResource(String rscType) { + // loop thru all the entries in the attrSetGroupsMap and return those + // that match the rscImpl + ArrayList attrSetGroupsList = new ArrayList(); - if( asg.getResource().equals( rscDefn.getResourceDefnName() ) ) { - attrSetGroupsList.add( asg ); - } - } - } + ResourceDefinition rscDefn = getResourceDefinition(rscType); - return attrSetGroupsList; + if (rscDefn == null) { + return attrSetGroupsList; + } else { + for (AttrSetGroup asg : attrSetGroupsMap.values()) { + + if (asg.getResource().equals(rscDefn.getResourceDefnName())) { + attrSetGroupsList.add(asg); + } + } + } + + return attrSetGroupsList; } - - public List getAttrSetGroupNamesForResource( String rscType ) { - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - List asgNameList = new ArrayList(); - - ArrayList asgList = getAttrSetGroupsForResource( rscType ); - - for( AttrSetGroup asg : asgList ) { - asgNameList.add( asg.getAttrSetGroupName() ); - } - return asgNameList; - //return ( rscDefn == null ? null : rscDefn.getAttrSetGroupNames() ); - } + public List getAttrSetGroupNamesForResource(String rscType) { + ResourceDefinition rscDefn = getResourceDefinition(rscType); + List asgNameList = new ArrayList(); - public AttributeSet getAttrSet( ResourceName rscName ) { //, String asName ) { - String asName = rscName.getRscAttrSetName(); - ResourceDefinition rscDefn = getResourceDefinition( rscName ); - String asgName = rscName.getRscGroup(); + ArrayList asgList = getAttrSetGroupsForResource(rscType); - return getAttrSet( rscDefn, asgName, asName ); - } - - // the asgName is not required but if given a sanity check will be done - // to ensure that the attrSet is actually in the given attrSetGroup. - // - public AttributeSet getAttrSet( ResourceDefinition rscDefn, String asName ) { - return getAttrSet( rscDefn, null, asName ); - } - - public AttributeSet getAttrSet( ResourceDefinition rscDefn, - String asgName, String asName ) { + for (AttrSetGroup asg : asgList) { + asgNameList.add(asg.getAttrSetGroupName()); + } - String asMapKey = (rscDefn.applyAttrSetGroups() ? - rscDefn.getRscImplementation() : rscDefn.getResourceDefnName() ); - - // - Map attrSetFiles = attrSetMap.get( asMapKey ); - - if( attrSetFiles == null || !attrSetFiles.containsKey( asName ) ) { -// out.println("Unable to find attrSet,"+asName+", for "+rscDefn.getResourceDefnName()); - return null; - } - - // if AttrSetGroups apply for this resource do a sanity check - // - if( rscDefn.applyAttrSetGroups() && - asgName != null && !asgName.isEmpty() ) { - - RscAndGroupName rscGrpName = new RscAndGroupName( rscDefn.getResourceDefnName(), asgName ); - - // Should we check that the asName is actually in the asGroup? - // - AttrSetGroup asg = getAttrSetGroupForResource( rscGrpName ); //attrSetGroupsMap.get( asgMapKey ); - - if( asg == null || !asg.getAttrSetNames().contains( asName ) ) { - out.println("Warning: AttrSet, "+asName+", is not in group "+asgName ); - return null; - } - } - - return attrSetFiles.get( asName ); - -// try { -// asLclFile.getFile( true ); // ?? force to retrieve file? -// return asLclFile; -// } -// catch( LocalizationException le ) { -// out.println("AttrSet,"+asName+", for "+rscName.toString()+" doesn't exist?" ); -// out.println( le.getLocalizedMessage() +"\n"+ le.getCause() ); -// return null; -// } - } - - - // get a list of all the available attribute sets for this resource defn. - // - public ArrayList getAvailAttrSets( ResourceDefinition rscDefn ) { - - String asMapKey = ( rscDefn.applyAttrSetGroups() ? - rscDefn.getRscImplementation() : rscDefn.getResourceDefnName() ); - if( !attrSetMap.containsKey( asMapKey ) ) { // ????? - return new ArrayList(); - } - - return new ArrayList( attrSetMap.get( asMapKey ).keySet() ); + return asgNameList; + // return ( rscDefn == null ? null : rscDefn.getAttrSetGroupNames() ); } - - // + + public AttributeSet getAttrSet(ResourceName rscName) { // , String asName ) + // { + String asName = rscName.getRscAttrSetName(); + ResourceDefinition rscDefn = getResourceDefinition(rscName); + String asgName = rscName.getRscGroup(); + + return getAttrSet(rscDefn, asgName, asName); + } + + // the asgName is not required but if given a sanity check will be done + // to ensure that the attrSet is actually in the given attrSetGroup. // - public ArrayList getAvailAttrSetsForRscImpl( String rscImpl ) { - ArrayList attrSetList = new ArrayList(); - if( attrSetMap.containsKey( rscImpl ) ) { - - attrSetList.addAll( attrSetMap.get( rscImpl ).keySet() ); - } - else { - out.println("No available attribute sets for "+rscImpl ); - } - return attrSetList; + public AttributeSet getAttrSet(ResourceDefinition rscDefn, String asName) { + return getAttrSet(rscDefn, null, asName); } - - - public List getAttrSetsForResource( ResourceName rscName, boolean matchGroup ) { - ResourceDefinition rscDefn = getResourceDefinition( rscName.getRscType() ); - List asList = new ArrayList(); - - if( rscDefn == null ) { - return null; - } - - if( rscDefn.applyAttrSetGroups() ) { - AttrSetGroup asg = getAttrSetGroupForResource( rscName ); - if( asg != null ) { - for( String asName : asg.getAttrSetNames() ) { - AttributeSet as = getAttrSet( rscDefn, asg.getAttrSetGroupName(), asName ); - if( as != null ){ - asList.add( as ); - } - } - } - } - else { - // if there is supposed to be a generated group but there is none - // then - if( matchGroup && - rscName.getRscGroup().isEmpty() && - !rscDefn.getSubTypeGenerator().isEmpty() ) { - } - else { - for( String asName : getAvailAttrSets( rscDefn ) ) { - AttributeSet as = getAttrSet( rscDefn, asName ); - if( as != null ){ - asList.add( as ); - } - } - } - } - - return asList; + + public AttributeSet getAttrSet(ResourceDefinition rscDefn, String asgName, + String asName) { + + String asMapKey = (rscDefn.applyAttrSetGroups() ? rscDefn + .getRscImplementation() : rscDefn.getResourceDefnName()); + + // + Map attrSetFiles = attrSetMap.get(asMapKey); + + if (attrSetFiles == null || !attrSetFiles.containsKey(asName)) { + // out.println("Unable to find attrSet,"+asName+", for "+rscDefn.getResourceDefnName()); + return null; + } + + // if AttrSetGroups apply for this resource do a sanity check + // + if (rscDefn.applyAttrSetGroups() && asgName != null + && !asgName.isEmpty()) { + + RscAndGroupName rscGrpName = new RscAndGroupName( + rscDefn.getResourceDefnName(), asgName); + + // Should we check that the asName is actually in the asGroup? + // + AttrSetGroup asg = getAttrSetGroupForResource(rscGrpName); // attrSetGroupsMap.get( + // asgMapKey + // ); + + if (asg == null || !asg.getAttrSetNames().contains(asName)) { + out.println("Warning: AttrSet, " + asName + + ", is not in group " + asgName); + return null; + } + } + + return attrSetFiles.get(asName); + + // try { + // asLclFile.getFile( true ); // ?? force to retrieve file? + // return asLclFile; + // } + // catch( LocalizationException le ) { + // out.println("AttrSet,"+asName+", for "+rscName.toString()+" doesn't exist?" + // ); + // out.println( le.getLocalizedMessage() +"\n"+ le.getCause() ); + // return null; + // } } - + + // get a list of all the available attribute sets for this resource defn. + // + public ArrayList getAvailAttrSets(ResourceDefinition rscDefn) { + + String asMapKey = (rscDefn.applyAttrSetGroups() ? rscDefn + .getRscImplementation() : rscDefn.getResourceDefnName()); + if (!attrSetMap.containsKey(asMapKey)) { // ????? + return new ArrayList(); + } + + return new ArrayList(attrSetMap.get(asMapKey).keySet()); + } + + // + // + public ArrayList getAvailAttrSetsForRscImpl(String rscImpl) { + ArrayList attrSetList = new ArrayList(); + if (attrSetMap.containsKey(rscImpl)) { + + attrSetList.addAll(attrSetMap.get(rscImpl).keySet()); + } else { + out.println("No available attribute sets for " + rscImpl); + } + return attrSetList; + } + + public List getAttrSetsForResource(ResourceName rscName, + boolean matchGroup) { + ResourceDefinition rscDefn = getResourceDefinition(rscName.getRscType()); + List asList = new ArrayList(); + + if (rscDefn == null) { + return null; + } + + if (rscDefn.applyAttrSetGroups()) { + AttrSetGroup asg = getAttrSetGroupForResource(rscName); + if (asg != null) { + for (String asName : asg.getAttrSetNames()) { + AttributeSet as = getAttrSet(rscDefn, + asg.getAttrSetGroupName(), asName); + if (as != null) { + asList.add(as); + } + } + } + } else { + // if there is supposed to be a generated group but there is none + // then + if (matchGroup && rscName.getRscGroup().isEmpty() + && !rscDefn.getSubTypeGenerator().isEmpty()) { + } else { + for (String asName : getAvailAttrSets(rscDefn)) { + AttributeSet as = getAttrSet(rscDefn, asName); + if (as != null) { + asList.add(as); + } + } + } + } + + return asList; + } + public List getAllSelectableResourceNamesForResourcDefn( - ResourceDefinition rscDefn ) throws VizException { - List rscNamesList = new ArrayList(); - - // build a list of all the possible requestable resourceNames - // - ResourceName rscName = new ResourceName(); - ResourceCategory rscCat = rscDefn.getResourceCategory(); - rscName.setRscCategory( rscCat ); + ResourceDefinition rscDefn) throws VizException { + List rscNamesList = new ArrayList(); - // TODO : need to improve the way this works. Never liked it. - // - List rscTypes = new ArrayList(); - -// if( rscDefn.getRscTypeGenerator().isEmpty() ) { -// rscTypes.add( rscDefn.getResourceDefnName() ); -// } -// else { -// rscTypes = rscDefn.getGeneratedTypesList(); -// } - - rscTypes.add( rscName.getRscType() ); - - for( String rscType : rscTypes ) { - ResourceDefinition rd = getResourceDefinition( rscType ); //: getResourceDefnsForCategory( rscCat, "", true, false ) ) { + // build a list of all the possible requestable resourceNames + // + ResourceName rscName = new ResourceName(); + ResourceCategory rscCat = rscDefn.getResourceCategory(); + rscName.setRscCategory(rscCat); -// // check that this is -// String rscType = rd.getResourceDefnName(); + // TODO : need to improve the way this works. Never liked it. + // + List rscTypes = new ArrayList(); - rscName.setRscType( rscType ); + // if( rscDefn.getRscTypeGenerator().isEmpty() ) { + // rscTypes.add( rscDefn.getResourceDefnName() ); + // } + // else { + // rscTypes = rscDefn.getGeneratedTypesList(); + // } - List asgList; + rscTypes.add(rscName.getRscType()); - if( rd.applyAttrSetGroups() ) { - asgList = getAttrSetGroupNamesForResource( rscType ); - } - else { - asgList = rd.generatedSubTypesList(); - } + for (String rscType : rscTypes) { + ResourceDefinition rd = getResourceDefinition(rscType); // : + // getResourceDefnsForCategory( + // rscCat, + // "", true, + // false ) ) + // { - if( asgList.isEmpty() ) { - rscName.setRscGroup( "" ); + // // check that this is + // String rscType = rd.getResourceDefnName(); - for( AttributeSet attrSet : getAttrSetsForResource(rscName, false ) ) { - rscName.setRscAttrSetName( attrSet.getName() ); - rscNamesList.add( new ResourceName( rscName ) ); - } - } - else { - for( String rscGroup : asgList ) { + rscName.setRscType(rscType); - rscName.setRscGroup( rscGroup ); + List asgList; - for( AttributeSet attrSet : getAttrSetsForResource( rscName, false ) ) { - rscName.setRscAttrSetName( attrSet.getName() ); - rscNamesList.add( new ResourceName( rscName ) ); - } - } - } - } - - return rscNamesList; + if (rd.applyAttrSetGroups()) { + asgList = getAttrSetGroupNamesForResource(rscType); + } else { + asgList = rd.generatedSubTypesList(); + } + + if (asgList.isEmpty()) { + rscName.setRscGroup(""); + + for (AttributeSet attrSet : getAttrSetsForResource(rscName, + false)) { + rscName.setRscAttrSetName(attrSet.getName()); + rscNamesList.add(new ResourceName(rscName)); + } + } else { + for (String rscGroup : asgList) { + + rscName.setRscGroup(rscGroup); + + for (AttributeSet attrSet : getAttrSetsForResource(rscName, + false)) { + rscName.setRscAttrSetName(attrSet.getName()); + rscNamesList.add(new ResourceName(rscName)); + } + } + } + } + + return rscNamesList; } - - public String getResourceImplementation( String rscType ) { - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - - return ( rscDefn == null ? null : rscDefn.getRscImplementation() ); + + public String getResourceImplementation(String rscType) { + ResourceDefinition rscDefn = getResourceDefinition(rscType); + + return (rscDefn == null ? null : rscDefn.getRscImplementation()); } - - // return true if the resource was replaced with another from a higher context level. + + // return true if the resource was replaced with another from a higher + // context level. // - public Boolean removeResourceDefn( ResourceDefinition rscDefn ) throws VizException { - if( rscDefn == null ) { - throw new VizException("Resource Defn is null?"); - } - LocalizationFile lFile = rscDefn.getLocalizationFile(); - - if( lFile == null ) { - throw new VizException("Resource Defn File is null?"); - } + public Boolean removeResourceDefn(ResourceDefinition rscDefn) + throws VizException { + if (rscDefn == null) { + throw new VizException("Resource Defn is null?"); + } + LocalizationFile lFile = rscDefn.getLocalizationFile(); - // sanity check (button should be disabled if BASE/SITE context) - if( lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER ) { - throw new VizException( "Can't Remove Base or Site Level Resource Types."); - } - - try { - String lFileName = lFile.getName(); -// int rscIndx = rscDefn.getDefinitionIndex(); - - lFile.delete(); -// PathManagerFactory.getPathManager(). - - rscDefn.dispose(); - - resourceDefnsMap.remove( rscDefn.getResourceDefnName() ); - - // get the BASE, SITE or DESK level file to replace the deleted one. - lFile = NcPathManager.getInstance().getStaticLocalizationFile( lFileName ); - - if( lFile != null ) { - // sanity check - if( lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - out.println("??? a User-level file still exists??"); - - lFile = NcPathManager.getInstance().getStaticLocalizationFile( lFileName ); - - Thread.sleep(1000); - - // It would be nice to know why this happens sometimes but for now this seems to - // fix the problem. - if( lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - throw new VizException("Error Removing Localization File: getStaticLocalizationFile returned a User level File."); - } - } - - if( lFile != null ) { - readResourceDefn( lFile ); // can throw VizException - } - } - - // remove the entry in the Filters file - if( rscFiltersMap.containsKey( rscDefn.getResourceDefnName() ) ) { // sanity check. Should be there. - TreeMap filtMap = rscFiltersMap.get( rscDefn.getResourceDefnName() ); - if( filtMap.containsKey( LocalizationLevel.USER ) ) { - filtMap.remove( LocalizationLevel.USER ); - saveResourceDefnFiltersFile(); - } - else { - System.out.println("sanity check: removing RD "+ rscDefn.getResourceDefnName()+". Missing USER level in the filtersTreeMap."); - } - } - else { - System.out.println("sanity check: removing RD "+ rscDefn.getResourceDefnName()+". Missing entry in the filtersMap."); - } + if (lFile == null) { + throw new VizException("Resource Defn File is null?"); + } - } catch( LocalizationOpFailedException e ) { - throw new VizException( e ); - } - catch (InterruptedException e) { - throw new VizException( e ); - } - catch( VizException e ) { - throw e; - } + // sanity check (button should be disabled if BASE/SITE context) + if (lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER) { + throw new VizException( + "Can't Remove Base or Site Level Resource Types."); + } - - return false; + try { + String lFileName = lFile.getName(); + // int rscIndx = rscDefn.getDefinitionIndex(); + + lFile.delete(); + // PathManagerFactory.getPathManager(). + + rscDefn.dispose(); + + resourceDefnsMap.remove(rscDefn.getResourceDefnName()); + + // get the BASE, SITE or DESK level file to replace the deleted one. + lFile = NcPathManager.getInstance().getStaticLocalizationFile( + lFileName); + + if (lFile != null) { + // sanity check + if (lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + out.println("??? a User-level file still exists??"); + + lFile = NcPathManager.getInstance() + .getStaticLocalizationFile(lFileName); + + Thread.sleep(1000); + + // It would be nice to know why this happens sometimes but + // for now this seems to + // fix the problem. + if (lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + throw new VizException( + "Error Removing Localization File: getStaticLocalizationFile returned a User level File."); + } + } + + if (lFile != null) { + readResourceDefn(lFile); // can throw VizException + } + } + + // remove the entry in the Filters file + if (rscFiltersMap.containsKey(rscDefn.getResourceDefnName())) { // sanity + // check. + // Should + // be + // there. + TreeMap filtMap = rscFiltersMap + .get(rscDefn.getResourceDefnName()); + if (filtMap.containsKey(LocalizationLevel.USER)) { + filtMap.remove(LocalizationLevel.USER); + saveResourceDefnFiltersFile(); + } else { + System.out.println("sanity check: removing RD " + + rscDefn.getResourceDefnName() + + ". Missing USER level in the filtersTreeMap."); + } + } else { + System.out.println("sanity check: removing RD " + + rscDefn.getResourceDefnName() + + ". Missing entry in the filtersMap."); + } + + } catch (LocalizationOpFailedException e) { + throw new VizException(e); + } catch (InterruptedException e) { + throw new VizException(e); + } catch (VizException e) { + throw e; + } + + return false; } - - // add/replace the given attrSetGroup in the map. - // - public void saveAttrSetGroup( AttrSetGroup attrSetGroup ) throws VizException { - if( attrSetGroup == null ) { - throw new VizException("null attr set group???"); - } - - LocalizationFile asgLclFile = attrSetGroup.getLocalizationFile(); - LocalizationContext asgLclContext = null; - String lFileName = null; - -// if( asgLclFile != null ) { -// asgLclContext = asgLclFile.getContext(); -// // if there is an existing file, use the same name. -// lFileName = asgLclFile.getName(); -// } -// else { // other wise create a new name - ResourceDefinition rscDefn = getResourceDefinition( attrSetGroup.getResource() ); - if( rscDefn == null ) { - throw new VizException("Unknown resource " + attrSetGroup.getResource() ); - } - - lFileName = NcPathConstants.ATTR_SET_GROUPS_DIR + File.separator + - rscDefn.getRscImplementation() + File.separator + - attrSetGroup.getResource()+"-"+ - attrSetGroup.getAttrSetGroupName() +".xml"; -// } - - // if this is not a USER level file, we need to create another - // Localization File at the USER Level - // - if( asgLclContext == null || - asgLclContext.getLocalizationLevel() != LocalizationLevel.USER ) { - - asgLclContext = pathMngr.getContext( - LocalizationType.CAVE_STATIC, LocalizationLevel.USER ); - - asgLclFile = pathMngr.getLocalizationFile( asgLclContext, lFileName ); - } - - try { - SerializationUtil.jaxbMarshalToXmlFile( attrSetGroup, - asgLclFile.getFile().getAbsolutePath() ); - asgLclFile.save(); - attrSetGroup.setLocalizationFile( asgLclFile ); - - if( attrSetGroupsMap.containsKey( attrSetGroup.getRscAndGroupName().toString() ) ) { - // System.out.println(attrSetGroup.getRscAndGroupName().toString()+" already in the map???"); - - } - - attrSetGroupsMap.put( attrSetGroup.getRscAndGroupName().toString(), attrSetGroup ); - - } catch (SerializationException e) { - throw new VizException("Error Serializing AttrSetGroup file:"+e.getMessage() ); - } catch (LocalizationOpFailedException e) { - throw new VizException("Error Localizing file:"+e.getMessage() ); - } + // add/replace the given attrSetGroup in the map. + // + public void saveAttrSetGroup(AttrSetGroup attrSetGroup) throws VizException { + if (attrSetGroup == null) { + throw new VizException("null attr set group???"); + } + + LocalizationFile asgLclFile = attrSetGroup.getLocalizationFile(); + LocalizationContext asgLclContext = null; + String lFileName = null; + + // if( asgLclFile != null ) { + // asgLclContext = asgLclFile.getContext(); + // // if there is an existing file, use the same name. + // lFileName = asgLclFile.getName(); + // } + // else { // other wise create a new name + ResourceDefinition rscDefn = getResourceDefinition(attrSetGroup + .getResource()); + if (rscDefn == null) { + throw new VizException("Unknown resource " + + attrSetGroup.getResource()); + } + + lFileName = NcPathConstants.ATTR_SET_GROUPS_DIR + File.separator + + rscDefn.getRscImplementation() + File.separator + + attrSetGroup.getResource() + "-" + + attrSetGroup.getAttrSetGroupName() + ".xml"; + // } + + // if this is not a USER level file, we need to create another + // Localization File at the USER Level + // + if (asgLclContext == null + || asgLclContext.getLocalizationLevel() != LocalizationLevel.USER) { + + asgLclContext = pathMngr.getContext(LocalizationType.CAVE_STATIC, + LocalizationLevel.USER); + + asgLclFile = pathMngr.getLocalizationFile(asgLclContext, lFileName); + } + + try { + SerializationUtil.jaxbMarshalToXmlFile(attrSetGroup, asgLclFile + .getFile().getAbsolutePath()); + + asgLclFile.save(); + attrSetGroup.setLocalizationFile(asgLclFile); + + if (attrSetGroupsMap.containsKey(attrSetGroup.getRscAndGroupName() + .toString())) { + // System.out.println(attrSetGroup.getRscAndGroupName().toString()+" already in the map???"); + + } + + attrSetGroupsMap.put(attrSetGroup.getRscAndGroupName().toString(), + attrSetGroup); + + } catch (SerializationException e) { + throw new VizException("Error Serializing AttrSetGroup file:" + + e.getMessage()); + } catch (LocalizationOpFailedException e) { + throw new VizException("Error Localizing file:" + e.getMessage()); + } } - - // remove this from the attrSetGroupsMap and remove the name from + + // remove this from the attrSetGroupsMap and remove the name from // the resource definition. - public void removeAttrSetGroup( String asgName, String rscType ) throws VizException { - // - ResourceDefinition rscDefn = getResourceDefinition( rscType ); - - if( rscDefn == null ) { - throw new VizException("Unable to find rscDefn "+ rscType ); - } - - AttrSetGroup asg = getAttrSetGroupForResource( new RscAndGroupName( rscType, asgName ) ); - - if( asg == null ) { - throw new VizException("Unable to find attrSetGroup "+ rscType+"/"+asgName ); - } - - LocalizationFile lFile = asg.getLocalizationFile(); - - if( lFile == null ) { - throw new VizException("Error Removing AttrSetGroup: LFile is null" ); - } - else if( lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER ) { - throw new VizException( "Can't Remove Base or Site Level Attribute Set Groups."); - } + public void removeAttrSetGroup(String asgName, String rscType) + throws VizException { + // + ResourceDefinition rscDefn = getResourceDefinition(rscType); - String lFileName = lFile.getName(); - - try { - lFile.delete(); + if (rscDefn == null) { + throw new VizException("Unable to find rscDefn " + rscType); + } - attrSetGroupsMap.remove( asg.getRscAndGroupName().toString() ); - - // get the BASE, SITE or DESK level file to replace the deleted one. - lFile = NcPathManager.getInstance().getStaticLocalizationFile( lFileName ); - - // - if( lFile == null ) { - throw new VizException("Can't find a Base or Superceding AttrSetGroup" ); -// rscDefn.removeAttrSetGroup( asgName ); - } + AttrSetGroup asg = getAttrSetGroupForResource(new RscAndGroupName( + rscType, asgName)); - // sanity check (is failing) - if( lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - out.println("??? a User-level ASG file still exists??"); - - try { Thread.sleep(1000); } catch (InterruptedException e) { } - - // TODO : Find out why this is happening and put in a better fix.... - lFile = NcPathManager.getInstance().getStaticLocalizationFile( lFileName ); - - if( lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - throw new VizException("Error Removing Attr Set Group: Still finding a User-level file?"); - } - } - - File asgFile = lFile.getFile(); - - if( !asgFile.exists() ) { - throw new VizException( "Can't open AttrSetGroup file: "+asgFile.getAbsolutePath() ); - } + if (asg == null) { + throw new VizException("Unable to find attrSetGroup " + rscType + + "/" + asgName); + } - try { - asg = SerializationUtil.jaxbUnmarshalFromXmlFile( - AttrSetGroup.class, asgFile.getAbsolutePath( ) ); + LocalizationFile lFile = asg.getLocalizationFile(); - } catch (SerializationException e) { - throw new VizException("Error Parsing file "+asgFile.getAbsolutePath( ) +"\n"+e.getMessage()); - } + if (lFile == null) { + throw new VizException("Error Removing AttrSetGroup: LFile is null"); + } else if (lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER) { + throw new VizException( + "Can't Remove Base or Site Level Attribute Set Groups."); + } - // add the ASG's in the list to the map. (PGEN is a special case since - // 1 'default' ASG applies to all PGEN resources.) - asg.setLocalizationFile( lFile ); - - String rscImpl=""; - ResourceDefinition asgRscDefn = getResourceDefinition( asg.getResource() ); + String lFileName = lFile.getName(); - if( asgRscDefn == null ) { - throw new VizException("AttrSetGroup file "+ - asgFile.getName() +" has a unknown resource:"+ - asg.getResource() ); - } + try { + lFile.delete(); - if( !asgRscDefn.isPgenResource() ) { - rscImpl = asgRscDefn.getRscImplementation(); + attrSetGroupsMap.remove(asg.getRscAndGroupName().toString()); - // validate that there is a resourceImpl for this attrSetGroup - // - if( !ResourceExtPointMngr.getInstance(). - getAvailResources().contains( rscImpl ) ) { - throw new VizException(( "Can't find Resource Implementation (class) for " + - "attrSetGroup : " + rscImpl + "\nThe Resource implementation should be specified in " + - "a NC-Resource extention point" ) ); - // don't fail; go ahead and put the attrset in the map - } - } + // get the BASE, SITE or DESK level file to replace the deleted one. + lFile = NcPathManager.getInstance().getStaticLocalizationFile( + lFileName); - attrSetGroupsMap.put( asg.getRscAndGroupName().toString(), asg ); - - } catch (LocalizationOpFailedException e) { - throw new VizException( e.getMessage() ); - } + // + if (lFile == null) { + throw new VizException( + "Can't find a Base or Superceding AttrSetGroup"); + // rscDefn.removeAttrSetGroup( asgName ); + } + + // sanity check (is failing) + if (lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + out.println("??? a User-level ASG file still exists??"); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + + // TODO : Find out why this is happening and put in a better + // fix.... + lFile = NcPathManager.getInstance().getStaticLocalizationFile( + lFileName); + + if (lFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + throw new VizException( + "Error Removing Attr Set Group: Still finding a User-level file?"); + } + } + + File asgFile = lFile.getFile(); + + if (!asgFile.exists()) { + throw new VizException("Can't open AttrSetGroup file: " + + asgFile.getAbsolutePath()); + } + + try { + asg = SerializationUtil.jaxbUnmarshalFromXmlFile( + AttrSetGroup.class, asgFile.getAbsolutePath()); + + } catch (SerializationException e) { + throw new VizException("Error Parsing file " + + asgFile.getAbsolutePath() + "\n" + e.getMessage()); + } + + // add the ASG's in the list to the map. (PGEN is a special case + // since + // 1 'default' ASG applies to all PGEN resources.) + asg.setLocalizationFile(lFile); + + String rscImpl = ""; + ResourceDefinition asgRscDefn = getResourceDefinition(asg + .getResource()); + + if (asgRscDefn == null) { + throw new VizException("AttrSetGroup file " + asgFile.getName() + + " has a unknown resource:" + asg.getResource()); + } + + if (!asgRscDefn.isPgenResource()) { + rscImpl = asgRscDefn.getRscImplementation(); + + // validate that there is a resourceImpl for this attrSetGroup + // + if (!ResourceExtPointMngr.getInstance().getAvailResources() + .contains(rscImpl)) { + throw new VizException( + ("Can't find Resource Implementation (class) for " + + "attrSetGroup : " + + rscImpl + + "\nThe Resource implementation should be specified in " + "a NC-Resource extention point")); + // don't fail; go ahead and put the attrset in the map + } + } + + attrSetGroupsMap.put(asg.getRscAndGroupName().toString(), asg); + + } catch (LocalizationOpFailedException e) { + throw new VizException(e.getMessage()); + } } - // - public void saveAttrSet( ResourceDefinition rscDefn, - String asName, //Map attrs, - String attrsStr ) throws VizException { - - String applicableRsc = - ( rscDefn.applyAttrSetGroups() ? rscDefn.getRscImplementation() : - rscDefn.getResourceDefnName() ); - - AttributeSet aSet = getAttrSet( rscDefn, asName ); - LocalizationFile lFile=null; - LocalizationContext userCntxt = - NcPathManager.getInstance().getContext( - LocalizationType.CAVE_STATIC, - LocalizationLevel.USER ); + // + public void saveAttrSet(ResourceDefinition rscDefn, String asName, // Map + // attrs, + String attrsStr) throws VizException { - boolean newAttrSet = (aSet == null); - - // create a new LocalizationFile. The path of the file is based on - // the resouce it applies to. - if( newAttrSet ) { - String attrSetLclName; - - if( rscDefn.applyAttrSetGroups() ) { - attrSetLclName = NcPathConstants.ATTR_SET_GROUPS_DIR+File.separator+ - rscDefn.getRscImplementation()+ - File.separator+asName+".attr"; - } - else { - attrSetLclName = rscDefn.getLocalizationFile().getName(); - attrSetLclName = attrSetLclName.substring(0, - attrSetLclName.lastIndexOf(File.separator))+ - File.separator +asName+".attr"; - } - - // create the path for localization to the config dir for the resource - lFile = NcPathManager.getInstance().getLocalizationFile( userCntxt, attrSetLclName ); - -// aSet = AttributeSet.createAttributeSet(applicableRsc, lFile); -// aSet.setFile( lFile ); - } - else { // if the aSet exists check that the context level is USER and change if needed - lFile = aSet.getFile(); - if( lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER ) { - - lFile = NcPathManager.getInstance().getLocalizationFile( userCntxt, lFile.getName() ); + String applicableRsc = (rscDefn.applyAttrSetGroups() ? rscDefn + .getRscImplementation() : rscDefn.getResourceDefnName()); - aSet.setFile( lFile ); - } - } - - try { - File newAttrSetFile = lFile.getFile(); + AttributeSet aSet = getAttrSet(rscDefn, asName); + LocalizationFile lFile = null; + LocalizationContext userCntxt = NcPathManager.getInstance().getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); - FileWriter fwriter = new FileWriter( newAttrSetFile ); - fwriter.write( attrsStr ); - fwriter.close(); - - lFile.save(); - - } catch (Exception e) { - throw new VizException( e ); - } - - // update the attrSetMap and attrSetGroupsMap with a new/renamed attrSet. - // - aSet = AttributeSet.createAttributeSet(applicableRsc, lFile); - - if( !attrSetMap.containsKey( applicableRsc ) ) { - // sanity check since this shouldn't happen. - attrSetMap.put( applicableRsc, new HashMap() ); - } + boolean newAttrSet = (aSet == null); - Map asFileMap = attrSetMap.get( applicableRsc ); - - // add or overwrite the localizationFile for this attrSet - - asFileMap.put( asName, aSet ); + // create a new LocalizationFile. The path of the file is based on + // the resouce it applies to. + if (newAttrSet) { + String attrSetLclName; + + if (rscDefn.applyAttrSetGroups()) { + attrSetLclName = NcPathConstants.ATTR_SET_GROUPS_DIR + + File.separator + rscDefn.getRscImplementation() + + File.separator + asName + ".attr"; + } else { + attrSetLclName = rscDefn.getLocalizationFile().getName(); + attrSetLclName = attrSetLclName.substring(0, + attrSetLclName.lastIndexOf(File.separator)) + + File.separator + asName + ".attr"; + } + + // create the path for localization to the config dir for the + // resource + lFile = NcPathManager.getInstance().getLocalizationFile(userCntxt, + attrSetLclName); + + // aSet = AttributeSet.createAttributeSet(applicableRsc, lFile); + // aSet.setFile( lFile ); + } else { // if the aSet exists check that the context level is USER and + // change if needed + lFile = aSet.getFile(); + if (lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER) { + + lFile = NcPathManager.getInstance().getLocalizationFile( + userCntxt, lFile.getName()); + + aSet.setFile(lFile); + } + } + + try { + File newAttrSetFile = lFile.getFile(); + + FileWriter fwriter = new FileWriter(newAttrSetFile); + fwriter.write(attrsStr); + fwriter.close(); + + lFile.save(); + + } catch (Exception e) { + throw new VizException(e); + } + + // update the attrSetMap and attrSetGroupsMap with a new/renamed + // attrSet. + // + aSet = AttributeSet.createAttributeSet(applicableRsc, lFile); + + if (!attrSetMap.containsKey(applicableRsc)) { + // sanity check since this shouldn't happen. + attrSetMap.put(applicableRsc, new HashMap()); + } + + Map asFileMap = attrSetMap.get(applicableRsc); + + // add or overwrite the localizationFile for this attrSet + + asFileMap.put(asName, aSet); } - - // remove the attr set file and remove the attr set name from the attr set groups + + // remove the attr set file and remove the attr set name from the attr set + // groups // that reference it // - public boolean removeAttrSet( ResourceName rscName ) throws VizException { + public boolean removeAttrSet(ResourceName rscName) throws VizException { - ResourceDefinition rscDefn = getResourceDefinition( rscName ); - if( rscDefn == null ) { - throw new VizException("???can't find rscDefn for "+rscName.toString() ); - } - - String attrSetName = rscName.getRscAttrSetName(); + ResourceDefinition rscDefn = getResourceDefinition(rscName); + if (rscDefn == null) { + throw new VizException("???can't find rscDefn for " + + rscName.toString()); + } - // delete the file and take it out of the rsc dfn list - LocalizationFile asLclFile = getAttrSet( rscName ).getFile();//, rscName.getRscAttrSetName() ); + String attrSetName = rscName.getRscAttrSetName(); - if( asLclFile == null ) { - throw new VizException("Attr Set File: "+asLclFile.getName()+" not found"); - } + // delete the file and take it out of the rsc dfn list + LocalizationFile asLclFile = getAttrSet(rscName).getFile();// , + // rscName.getRscAttrSetName() + // ); - // sanity check (button should be disabled if BASE/SITE context) - if( asLclFile.getContext().getLocalizationLevel() != LocalizationLevel.USER ) { - throw new VizException( "Can't Remove Base or Site Level Attribute Sets."); - } - - try { - String lFileName = asLclFile.getName(); - - if( attrSetMap.containsKey( rscDefn.getResourceDefnName() ) ) { - attrSetMap.get( rscDefn.getResourceDefnName()).remove( attrSetName ); - } - - // TODO : call NcPathManager method to delete and return superceding file - // from BASE or SITE and add this to the map. - asLclFile.delete(); - - // get the BASE, SITE or DESK level file to replace the deleted one. - asLclFile = NcPathManager.getInstance().getStaticLocalizationFile( lFileName ); - - if( asLclFile != null ) { - // sanity check - if( asLclFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - out.println("??? a User-level file still exists??"); + if (asLclFile == null) { + throw new VizException("Attr Set File: " + asLclFile.getName() + + " not found"); + } - try { Thread.sleep(1000); } catch (InterruptedException e) { } - - // TODO : Find out why this is happening and put in a better fix.... - asLclFile = NcPathManager.getInstance().getStaticLocalizationFile( lFileName ); - - if( asLclFile.getContext().getLocalizationLevel() == LocalizationLevel.USER ) { - throw new VizException("Error Removing Attr Set: Still finding a User-level file?"); - } - } - - String rscImpl = asLclFile.getFile().getParentFile().getName(); + // sanity check (button should be disabled if BASE/SITE context) + if (asLclFile.getContext().getLocalizationLevel() != LocalizationLevel.USER) { + throw new VizException( + "Can't Remove Base or Site Level Attribute Sets."); + } - if( !attrSetMap.containsKey( rscImpl ) ) { - attrSetMap.put( rscImpl, new HashMap() ); - } - try { - AttributeSet aSet = AttributeSet.createAttributeSet(rscImpl, asLclFile ); - - attrSetMap.get( rscImpl ).put( aSet.getName(), aSet ); - } - catch ( VizException e ) { - out.println("Error Creating AttributeSet "+ asLclFile.getName() + - ": "+ e.getMessage() ); - } - } - - } catch ( LocalizationOpFailedException lopex ) { - throw new VizException( lopex.getMessage() ); - } + try { + String lFileName = asLclFile.getName(); - // if removing an attr set that is part of a group then check for references - // to it in other groups and edit and save the groups - // - if( rscDefn.applyAttrSetGroups() ) { - String rscImpl = rscDefn.getRscImplementation(); -// String attrSetGroup = rscName.getRscGroup(); + if (attrSetMap.containsKey(rscDefn.getResourceDefnName())) { + attrSetMap.get(rscDefn.getResourceDefnName()).remove( + attrSetName); + } - for( AttrSetGroup asg : attrSetGroupsMap.values() ) { - // if this is a BASE or SITE level group then it can't reference a user-defined attrSet. - // - if( asg.getLocalizationFile().getContext().getLocalizationLevel() == LocalizationLevel.USER && - asg.getResource().equals( rscDefn.getResourceDefnName() ) ) { - - if( asg.getAttrSetNames().contains( attrSetName ) ) { - asg.removeAttrSet( attrSetName ); - - saveAttrSetGroup( asg ); - } - } - } - - // loop thru all the resources for this implementation and - // check if there is a reference to this attrSet. - for( String rscType : getRscTypesForRscImplementation( rscImpl ) ) { + // TODO : call NcPathManager method to delete and return superceding + // file + // from BASE or SITE and add this to the map. + asLclFile.delete(); - ResourceDefinition rd = getResourceDefinition( rscType ); + // get the BASE, SITE or DESK level file to replace the deleted one. + asLclFile = NcPathManager.getInstance().getStaticLocalizationFile( + lFileName); - if( rd == null ) { // sanity check - continue; - } - - // loop thru all of the attrSetGroups for this resource - // - for( AttrSetGroup asg : getAttrSetGroupsForResource( rscType ) ) { - - if( asg != null && - asg.getAttrSetNames().contains( attrSetName ) ) { - - asg.removeAttrSet( attrSetName ); - saveAttrSetGroup( asg ); - } - } - } - } - - return true; + if (asLclFile != null) { + // sanity check + if (asLclFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + out.println("??? a User-level file still exists??"); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + + // TODO : Find out why this is happening and put in a better + // fix.... + asLclFile = NcPathManager.getInstance() + .getStaticLocalizationFile(lFileName); + + if (asLclFile.getContext().getLocalizationLevel() == LocalizationLevel.USER) { + throw new VizException( + "Error Removing Attr Set: Still finding a User-level file?"); + } + } + + String rscImpl = asLclFile.getFile().getParentFile().getName(); + + if (!attrSetMap.containsKey(rscImpl)) { + attrSetMap + .put(rscImpl, new HashMap()); + } + try { + AttributeSet aSet = AttributeSet.createAttributeSet( + rscImpl, asLclFile); + + attrSetMap.get(rscImpl).put(aSet.getName(), aSet); + } catch (VizException e) { + out.println("Error Creating AttributeSet " + + asLclFile.getName() + ": " + e.getMessage()); + } + } + + } catch (LocalizationOpFailedException lopex) { + throw new VizException(lopex.getMessage()); + } + + // if removing an attr set that is part of a group then check for + // references + // to it in other groups and edit and save the groups + // + if (rscDefn.applyAttrSetGroups()) { + String rscImpl = rscDefn.getRscImplementation(); + // String attrSetGroup = rscName.getRscGroup(); + + for (AttrSetGroup asg : attrSetGroupsMap.values()) { + // if this is a BASE or SITE level group then it can't reference + // a user-defined attrSet. + // + if (asg.getLocalizationFile().getContext() + .getLocalizationLevel() == LocalizationLevel.USER + && asg.getResource().equals( + rscDefn.getResourceDefnName())) { + + if (asg.getAttrSetNames().contains(attrSetName)) { + asg.removeAttrSet(attrSetName); + + saveAttrSetGroup(asg); + } + } + } + + // loop thru all the resources for this implementation and + // check if there is a reference to this attrSet. + for (String rscType : getRscTypesForRscImplementation(rscImpl)) { + + ResourceDefinition rd = getResourceDefinition(rscType); + + if (rd == null) { // sanity check + continue; + } + + // loop thru all of the attrSetGroups for this resource + // + for (AttrSetGroup asg : getAttrSetGroupsForResource(rscType)) { + + if (asg != null + && asg.getAttrSetNames().contains(attrSetName)) { + + asg.removeAttrSet(attrSetName); + saveAttrSetGroup(asg); + } + } + } + } + + return true; } - - - public ArrayList getRscTypesForRscImplementation( String rscImpl ) { - ArrayList rscTypes = new ArrayList(); - - for( ResourceDefinition rscDefn : resourceDefnsMap.values() ) { - if( rscDefn.getRscImplementation().equals( rscImpl ) ) { - rscTypes.add( rscDefn.getResourceDefnName() ); - } - } - return rscTypes; + + public ArrayList getRscTypesForRscImplementation(String rscImpl) { + ArrayList rscTypes = new ArrayList(); + + for (ResourceDefinition rscDefn : resourceDefnsMap.values()) { + if (rscDefn.getRscImplementation().equals(rscImpl)) { + rscTypes.add(rscDefn.getResourceDefnName()); + } + } + return rscTypes; } - - // get a list of all the USER-level RD filters and save them to the Filters file. + + // get a list of all the USER-level RD filters and save them to the Filters + // file. public void saveResourceDefnFiltersFile() throws VizException { - ResourceDefinitionFilters rscDfnFilters = new ResourceDefinitionFilters(); + ResourceDefinitionFilters rscDfnFilters = new ResourceDefinitionFilters(); - // loop thru the user-level filters - // TODO : give the RDs a meaningful ordering. - for( String rdName : rscFiltersMap.keySet() ) { - - // get the highest priority filters. (stored in reverse order) - TreeMap filtMap = rscFiltersMap.get( rdName ); - ResourceDefinitionFilter rdFilt = filtMap.get( LocalizationLevel.USER ); - - if( rdFilt != null ) { - rscDfnFilters.getResourceDefinitionFiltersList().add( rdFilt ); - } - } - -// NOTE : should we 'patch' anything that may be out of order/missing. -// for( ResourceDefinition rd : resourceDefnsMap.values() ) { -// if( rscDfnFilters.; -// } + // loop thru the user-level filters + // TODO : give the RDs a meaningful ordering. + for (String rdName : rscFiltersMap.keySet()) { - LocalizationContext context = pathMngr.getContext( - LocalizationType.CAVE_STATIC, LocalizationLevel.USER ); + // get the highest priority filters. (stored in reverse order) + TreeMap filtMap = rscFiltersMap + .get(rdName); + ResourceDefinitionFilter rdFilt = filtMap + .get(LocalizationLevel.USER); - LocalizationFile rscFiltersLFile = pathMngr.getLocalizationFile( context, NcPathConstants.RESOURCE_FILTERS ); + if (rdFilt != null) { + rscDfnFilters.getResourceDefinitionFiltersList().add(rdFilt); + } + } - try { - SerializationUtil.jaxbMarshalToXmlFile( - rscDfnFilters, rscFiltersLFile.getFile().getAbsolutePath() ); + // NOTE : should we 'patch' anything that may be out of order/missing. + // for( ResourceDefinition rd : resourceDefnsMap.values() ) { + // if( rscDfnFilters.; + // } - rscFiltersLFile.save(); - } catch (LocalizationOpFailedException e) { - throw new VizException( e ); - } catch (SerializationException e) { - throw new VizException( e ); - } + LocalizationContext context = pathMngr.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + + LocalizationFile rscFiltersLFile = pathMngr.getLocalizationFile( + context, NcPathConstants.RESOURCE_FILTERS); + + try { + SerializationUtil.jaxbMarshalToXmlFile(rscDfnFilters, + rscFiltersLFile.getFile().getAbsolutePath()); + + rscFiltersLFile.save(); + } catch (LocalizationOpFailedException e) { + throw new VizException(e); + } catch (SerializationException e) { + throw new VizException(e); + } } - - // put the new/edited rscDefn in the map, write it out and initialize the inventory + + // put the new/edited rscDefn in the map, write it out and initialize the + // inventory // - public boolean saveResourceDefn( ResourceDefinition rscDefn ) throws VizException { - - rscDefn.validateResourceParameters( ); - - boolean createRscDefn = ( getResourceDefinition( rscDefn.getResourceDefnName() ) == null ); + public boolean saveResourceDefn(ResourceDefinition rscDefn) + throws VizException { - LocalizationFile lFile;// ; - LocalizationContext userContext = NcPathManager.getInstance().getContext( - LocalizationType.CAVE_STATIC, LocalizationLevel.USER ); - - // if this is a new rsc the LocalizationFile should not be set but the name should be. - if( createRscDefn ) { - lFile = NcPathManager.getInstance().getLocalizationFile( userContext, - rscDefn.getLocalizationName() ); - } - else { - lFile = rscDefn.getLocalizationFile(); - - if( lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER ) { - lFile = NcPathManager.getInstance().getLocalizationFile( userContext, - lFile.getName() ); - } - } - - rscDefn.setLocalizationFile( lFile ); - - try { - SerializationUtil.jaxbMarshalToXmlFile( rscDefn, - lFile.getFile().getAbsolutePath() ); + rscDefn.validateResourceParameters(); - lFile.save(); - + boolean createRscDefn = (getResourceDefinition(rscDefn + .getResourceDefnName()) == null); - List rdList = new ArrayList(); - rdList.add( rscDefn ); - - List errList = findOrCreateInventoryForRscDefns( rdList ); + LocalizationFile lFile;// ; + LocalizationContext userContext = NcPathManager.getInstance() + .getContext(LocalizationType.CAVE_STATIC, + LocalizationLevel.USER); - if( errList.isEmpty() ) { - resourceDefnsMap.put( rscDefn.getResourceDefnName(), rscDefn ); - } - else { - throw new VizException( "Error finding or Creating Inventory."); - } - - // check to see if there is an inventory for this rscDefn or if - // we need to create one. - // -// NcInventoryDefinition invDefn = rscDefn.createNcInventoryDefinition(); -// -// // reload just in case they have changed. -// Map invDefnsMap = null; -// -// try { -// invDefnsMap = getInventoryDefinitions(); -// } -// catch (VizException ve ) { -// System.out.println(ve.getMessage()); -// invDefnsMap = new HashMap(); -// } -// -// if( invDefnsMap.containsKey( invDefn ) ) { -// rscDefn.setInventoryAlias( invDefnsMap.get( invDefn ).getInventoryName() ); -// } -// -// if( rscDefn.usesInventory() ) { -// InventoryLoaderJob invLoader = new InventoryLoaderJob( invDefn, false ); -// -// invLoader.schedule(); -// -// // update the progress monitor -// while( invLoader.getNumberOfInventoriesLeftToLoad() > 0 ) { -// try { -// Thread.sleep(400); -// } catch (InterruptedException e) { -// } -// } -// -// if( invLoader.getUninitializedInventoryDefns().length == 1 ) { -// rscDefn.setInventoryAlias( null ); // Initialized( false ); -// rscDefn.disableInventoryUse(); -// -// throw new VizException("There was an error Initializing an Inventory : Disabling Inventory Use" ); -// } -// -// rscDefn.setInventoryAlias( invDefn.getInventoryName() );//Initialized( true ); -// } -// -// if( rscDefn.getInventoryEnabled() ) { -// rscDefn.enableInventoryUse(); -// } -// else { -// rscDefn.disableInventoryUse(); -// } -// - } catch (SerializationException e) { - throw new VizException("Error Serializing AttrSetGroup file:"+e.getMessage() ); - } catch (LocalizationOpFailedException e) { - throw new VizException("Error Localizing file:"+e.getMessage() ); - } + // if this is a new rsc the LocalizationFile should not be set but the + // name should be. + if (createRscDefn) { + lFile = NcPathManager.getInstance().getLocalizationFile( + userContext, rscDefn.getLocalizationName()); + } else { + lFile = rscDefn.getLocalizationFile(); - return true; + if (lFile.getContext().getLocalizationLevel() != LocalizationLevel.USER) { + lFile = NcPathManager.getInstance().getLocalizationFile( + userContext, lFile.getName()); + } + } + + rscDefn.setLocalizationFile(lFile); + + try { + SerializationUtil.jaxbMarshalToXmlFile(rscDefn, lFile.getFile() + .getAbsolutePath()); + + lFile.save(); + + List rdList = new ArrayList(); + rdList.add(rscDefn); + + List errList = findOrCreateInventoryForRscDefns(rdList); + + if (errList.isEmpty()) { + resourceDefnsMap.put(rscDefn.getResourceDefnName(), rscDefn); + } else { + throw new VizException("Error finding or Creating Inventory."); + } + + // check to see if there is an inventory for this rscDefn or if + // we need to create one. + // + // NcInventoryDefinition invDefn = + // rscDefn.createNcInventoryDefinition(); + // + // // reload just in case they have changed. + // Map invDefnsMap = + // null; + // + // try { + // invDefnsMap = getInventoryDefinitions(); + // } + // catch (VizException ve ) { + // System.out.println(ve.getMessage()); + // invDefnsMap = new + // HashMap(); + // } + // + // if( invDefnsMap.containsKey( invDefn ) ) { + // rscDefn.setInventoryAlias( invDefnsMap.get( invDefn + // ).getInventoryName() ); + // } + // + // if( rscDefn.usesInventory() ) { + // InventoryLoaderJob invLoader = new InventoryLoaderJob( invDefn, + // false ); + // + // invLoader.schedule(); + // + // // update the progress monitor + // while( invLoader.getNumberOfInventoriesLeftToLoad() > 0 ) { + // try { + // Thread.sleep(400); + // } catch (InterruptedException e) { + // } + // } + // + // if( invLoader.getUninitializedInventoryDefns().length == 1 ) { + // rscDefn.setInventoryAlias( null ); // Initialized( false ); + // rscDefn.disableInventoryUse(); + // + // throw new + // VizException("There was an error Initializing an Inventory : Disabling Inventory Use" + // ); + // } + // + // rscDefn.setInventoryAlias( invDefn.getInventoryName() + // );//Initialized( true ); + // } + // + // if( rscDefn.getInventoryEnabled() ) { + // rscDefn.enableInventoryUse(); + // } + // else { + // rscDefn.disableInventoryUse(); + // } + // + } catch (SerializationException e) { + throw new VizException("Error Serializing AttrSetGroup file:" + + e.getMessage()); + } catch (LocalizationOpFailedException e) { + throw new VizException("Error Localizing file:" + e.getMessage()); + } + + return true; } - + public ResourceDefinition getLocatorResourceDefinition() { - return locatorRscDefn; + return locatorRscDefn; } } diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java index 43ac2eb526..fe24e4e558 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/manager/RscBundleDisplayMngr.java @@ -1,23 +1,19 @@ package gov.noaa.nws.ncep.viz.resources.manager; -import gov.noaa.nws.ncep.viz.common.area.AreaMenus; +import gov.noaa.nws.ncep.viz.common.area.AreaMenus.AreaMenuItem; import gov.noaa.nws.ncep.viz.common.area.AreaMenusMngr; import gov.noaa.nws.ncep.viz.common.area.AreaName; -import gov.noaa.nws.ncep.viz.common.area.AreaMenus.AreaMenuItem; import gov.noaa.nws.ncep.viz.common.area.AreaName.AreaSource; import gov.noaa.nws.ncep.viz.common.area.IAreaProviderCapable; import gov.noaa.nws.ncep.viz.common.area.IGridGeometryProvider; -import gov.noaa.nws.ncep.viz.common.area.INcAreaProviderFactory; +import gov.noaa.nws.ncep.viz.common.area.IGridGeometryProvider.ZoomLevelStrings; import gov.noaa.nws.ncep.viz.common.area.NcAreaProviderMngr; import gov.noaa.nws.ncep.viz.common.area.PredefinedArea; import gov.noaa.nws.ncep.viz.common.area.PredefinedAreaFactory; -import gov.noaa.nws.ncep.viz.common.area.IGridGeometryProvider.ZoomLevelStrings; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; -import gov.noaa.nws.ncep.viz.common.display.INatlCntrsPaneManager; import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; import gov.noaa.nws.ncep.viz.common.display.INcPaneID; import gov.noaa.nws.ncep.viz.common.display.INcPaneLayout; -import gov.noaa.nws.ncep.viz.common.display.IPaneLayoutable; import gov.noaa.nws.ncep.viz.common.display.NcDisplayName; import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; import gov.noaa.nws.ncep.viz.common.ui.NmapCommon; @@ -25,14 +21,13 @@ import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; import gov.noaa.nws.ncep.viz.resources.manager.ResourceFactory.ResourceSelection; import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; -import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; -import gov.noaa.nws.ncep.viz.ui.display.NcPaneLayout; import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; +import gov.noaa.nws.ncep.viz.ui.display.NcEditorUtil; import gov.noaa.nws.ncep.viz.ui.display.NcPaneID; +import gov.noaa.nws.ncep.viz.ui.display.NcPaneLayout; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,13 +38,11 @@ import org.eclipse.jface.dialogs.MessageDialog; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.rsc.DisplayType; import com.raytheon.viz.ui.editor.AbstractEditor; - /** - * Mngr class for the Selection and Creation of RBDs from the Resource - * Bundle Display Dialog. + * Mngr class for the Selection and Creation of RBDs from the Resource Bundle + * Display Dialog. * *
  * SOFTWARE HISTORY
@@ -84,1063 +77,1146 @@ import com.raytheon.viz.ui.editor.AbstractEditor;
  *                                         and use new areaProvider sources.
  * 11/25/2013   #1078      Greg Hull       check for FitToScreen and SizeOfImage in setPaneData()
  * 11/25/2013   #1079      Greg Hull       checkAndUpdateAreaFromResource
- *
+ * 05/15/2014   #1131      Quan Zhou       added rbdType GRAPH_DISPLAY
  * 
* * @author ghull * @version 1 */ -public class RscBundleDisplayMngr { - - public static class PaneSelectionData { - private RscBundleDisplayMngr rscBndlMngr=null; - -// private class RenderingOrderComparator implements Comparator { -// -// @Override -// public int compare(ResourceSelection o1, ResourceSelection o2) { -// Integer i1 = o1.getRenderingOrder(); -// Integer i2 = o2.getRenderingOrder(); -// return i1.compareTo(i2); -// } -// } +public class RscBundleDisplayMngr { - private Vector seldResources = new Vector(); - - // if set with a 'custom' area defined by an RBD then this will - // be set to the custom area. Since it can't be accessed by an areaFactory - // until it is loaded, this is use to reset the area should the user reselect - // the custom area from the gui. - private PredefinedArea initialArea = null; - - private PredefinedArea area = null; - - // we could use this if we want to be able to reset the area's if - // the user accidently changes all of them with the geoSync button. - //private String prevSeldGeogArea = null; + public static class PaneSelectionData { + private RscBundleDisplayMngr rscBndlMngr = null; - public PaneSelectionData( RscBundleDisplayMngr rbdm, NcDisplayType rbdType ) { - rscBndlMngr = rbdm; - seldResources = new Vector(); - - try { - area = PredefinedAreaFactory.getDefaultPredefinedAreaForDisplayType( rbdType ); - } catch (VizException e1) { - System.out.println("Error getting default PredefinedArea: "+e1.getMessage() ); - } - - // Reference the same base overlay for multi-pane displays. - if( baseOverlayResources.containsKey( rbdType ) ) { - seldResources.add( baseOverlayResources.get( rbdType ) ); - } - } - - public PredefinedArea getInitialArea() { - return initialArea; - } + // private class RenderingOrderComparator implements + // Comparator { + // + // @Override + // public int compare(ResourceSelection o1, ResourceSelection o2) { + // Integer i1 = o1.getRenderingOrder(); + // Integer i2 = o2.getRenderingOrder(); + // return i1.compareTo(i2); + // } + // } - public PredefinedArea getArea() { - return area; - } + private Vector seldResources = new Vector(); - // bit of a hack here. null indicates to reset to a custom area from an rbd - // that was initially set from an earlier call to setArea() where the source - // was the INITIAL_DISPLAY_AREA from an RBD. - public void setArea( PredefinedArea pa ) { - if( pa == null ) { - area = initialArea; - } - else { - area = pa; - if( initialArea == null || - area.getSource() == AreaSource.INITIAL_DISPLAY_AREA ) { - initialArea = area; - } - } - } - - public void setZoomLevel( String zl ) { - area.setZoomLevel( zl ); - } - - public ResourceSelection[] getSelectedResources() { - return seldResources.toArray( new ResourceSelection[0] ); - } - - // Don't add the same resource twice. If this is the base overlay, - // replace the existing base overlay. - public boolean addSelectedResource( ResourceSelection rbt ) { -// for( ResourceSelection r : seldResources ) { - for( int r=0 ; r(); - maxLayout = maxPaneLayout; - init( dispType ); - } + try { + area = PredefinedAreaFactory + .getDefaultPredefinedAreaForDisplayType(rbdType); + } catch (VizException e1) { + System.out.println("Error getting default PredefinedArea: " + + e1.getMessage()); + } - // the maximum number of rows & columns - private NcPaneLayout maxLayout = new NcPaneLayout(6,6); - - // an RBD must be one of these display types and all resources in the RBD must be compatible - // with the display type. - private NcDisplayType rbdType; + // Reference the same base overlay for multi-pane displays. + if (baseOverlayResources.containsKey(rbdType)) { + seldResources.add(baseOverlayResources.get(rbdType)); + } + } - // the currently selected layout (numRows,numColumns) - private INcPaneLayout currRbdPaneLayout = new NcPaneLayout(1,1); - - // the currently selected pane - private NcPaneID selectedPaneId = new NcPaneID(); // 0,0 - - // this will map the paneID (as a string) to the current area and resource - // information . Note : use a String since the paneIndex is relative to the - // selected paneLayout which may change. - private HashMap paneSelectionDataMap = - new HashMap(); - - // the entry in the paneSelectionDataMap that is currently selected - private PaneSelectionData selectedPaneData = null; - - // base resources can't be removed and are the same instance for all panes. - // ie. the geopolitical overlay. - private static Map baseOverlayResources = new HashMap(); - - private boolean geoSyncPanes = false; - private boolean autoUpdate = false; + public PredefinedArea getInitialArea() { + return initialArea; + } - private boolean multiPane = false; - - private String rbdName = ""; - - // set to true here if any of the resources, currRbdPaneLayout,... is changed. Reset to false here - // if initialized. Set to true from the dialog if a resource is edited or if the rbd is cleared. - private boolean rbdModified = false; - - // the initial timeMatcher from an AbstractRBD. This may be superceded by - // any changes from the GUI. - private NCTimeMatcher initialTimeMatcher = null; - - public NcPaneLayout getMaxPaneLayout() { - return maxLayout; - } - - public boolean isRbdModified() { - return rbdModified; - } + public PredefinedArea getArea() { + return area; + } - public void setRbdModified(boolean rbdModified) { - this.rbdModified = rbdModified; - } + // bit of a hack here. null indicates to reset to a custom area from an + // rbd + // that was initially set from an earlier call to setArea() where the + // source + // was the INITIAL_DISPLAY_AREA from an RBD. + public void setArea(PredefinedArea pa) { + if (pa == null) { + area = initialArea; + } else { + area = pa; + if (initialArea == null + || area.getSource() == AreaSource.INITIAL_DISPLAY_AREA) { + initialArea = area; + } + } + } - public boolean isMultiPane() { - return multiPane; - } + public void setZoomLevel(String zl) { + area.setZoomLevel(zl); + } - // note that the currRbdPaneLayout will stay the same to hold any selections - // in case the user turns multipane back on again. - public void setMultiPane(boolean multiPane) { - if( this.multiPane == multiPane ) { - return; - } - rbdModified = true; - - this.multiPane = multiPane; - } + public ResourceSelection[] getSelectedResources() { + return seldResources.toArray(new ResourceSelection[0]); + } - // note that if multipane is false then only the 1,1 pane will be used - public INcPaneLayout getPaneLayout() { - return currRbdPaneLayout; - } - - // return the selected paneId so the caller may tell if it changed. - public INcPaneID setPaneLayout( INcPaneLayout paneLayout) { - if( this.currRbdPaneLayout.equals( paneLayout ) ) { - return selectedPaneId; - } - - rbdModified = true; - -// if( paneLayout.getRows() <= selectedPaneId.getRow() ) { -// selectedPaneId = new NcPaneID( selectedPaneId.getRow()-1, -// selectedPaneId.getColumn() ); -// } -// if( paneLayout.getColumns() <= selectedPaneId.getColumn() ) { -// selectedPaneId = new NcPaneID( selectedPaneId.getRow(), -// selectedPaneId.getColumn()-1 ); -// } - if( !paneLayout.containsPaneId( selectedPaneId ) ) { - selectedPaneId = new NcPaneID(); - } - - currRbdPaneLayout = paneLayout; - - setMultiPane( paneLayout.getNumberOfPanes() > 1 ); - -// // make sure there is an entry in the map for each pane -// for( int p=0 ; p rbdBndl ) throws VizException { - - // reset all panes and then set the PaneData for those in the rbd. - init( rbdBndl.getDisplayType() ); - - // TODO : don't set the rbdName if it is the default RBD as a - setRbdType( rbdBndl.getDisplayType() ); - setRbdName( rbdBndl.getRbdName() ); - setPaneLayout( rbdBndl.getPaneLayout() ); - setAutoUpdate( rbdBndl.isAutoUpdate() ); - setGeoSyncPanes( rbdBndl.isGeoSyncedPanes() ); - - // loop through each of the panes and initialize the paneData to the - // selections in the rbd. - for( int paneIndx=0 ; paneIndx 0 && //dispPane.getPaneManager() instanceof NCPaneManager && - dispPane instanceof IAreaProviderCapable ) { - - // the name of the display's area will be the name of the pane. - AreaName currDispAreaName = new AreaName( AreaSource.DISPLAY_AREA, - ((IAreaProviderCapable)dispPane).getAreaName() ); - try { - IGridGeometryProvider currGeom = NcAreaProviderMngr.createGeomProvider( currDispAreaName ); - - // the name of the selected area will be the current area of the imported display - // unless the area has not been changed and the initial area is a predefined area - if( currGeom != null && initialArea != null ) { // sanity check - - PredefinedArea currArea = PredefinedAreaFactory.createPredefinedArea(currGeom); - - // The areAreasEqual method doesn't work on SizeOfImage. This will lock the zoom - // so we will assume that if the initial area is SizeOfImage that the initial area - // is the - if( !initialArea.getZoomLevel().equals( ZoomLevelStrings.SizeOfImage.toString() ) && - !initialArea.getZoomLevel().equals( ZoomLevelStrings.FitToScreen.toString() ) ) { - - // use the area of the current display if the areas are different - // or if the same but the initial area is not a named/saved area name. - // - if( PredefinedArea.areAreasEqual( initialArea, currArea ) ) { - if( initialArea.getSource() == AreaSource.INITIAL_DISPLAY_AREA ) { - // seldAreaName = currDispAreaName; - seldPredefinedArea = currArea; - } - } - else { - // seldAreaName = currDispAreaName; - seldPredefinedArea = currArea; - } - } - } - } - catch ( VizException ve ) { - System.out.println("error getting curr area for "+dispPane.getPaneName() ); - } - } + for (NcDisplayType dt : NcDisplayType.getRbdSavableDisplayTypes()) { + if (dt.getBaseResource() != null && !dt.getBaseResource().isEmpty()) { - try { - setSelectedArea( seldPredefinedArea ); - } - catch ( VizException ve ) { - setSelectedAreaName( - new AreaName( AreaSource.PREDEFINED_AREA, rbdType.getDefaultMap() ) ); - } - -// setSelectedPaneId( paneId ); - } + ResourceName rscName = new ResourceName(dt.getBaseResource()); + try { + if (rscName.isValid()) { + ResourceSelection baseOverlay = ResourceFactory + .createResource(rscName); + baseOverlay.setIsBaseLevelResource(true); + baseOverlayResources.put(dt, baseOverlay); + } else { + throw new VizException("Invalid base overlay name " + + rscName.toString() + " for display type: " + + dt.toString()); + } - public ResourceSelection[] getSelectedRscs() { - return selectedPaneData.getSelectedResources(); - } + } catch (VizException e) { + MessageDialog errDlg = new MessageDialog( + NcDisplayMngr.getCaveShell(), "Error", null, + "Error creating base overlay for " + dt.getName() + + " RBDs:" + rscName.toString() + "\n" + + e.getMessage(), MessageDialog.ERROR, + new String[] { "OK" }, 0); + errDlg.open(); + } + } + } - public ResourceSelection[] getRscsForPane( INcPaneID paneId ) { - if( !paneSelectionDataMap.containsKey( paneId.toString() ) ) { - return new ResourceSelection[]{}; - } - return paneSelectionDataMap.get( paneId.toString() ).getSelectedResources(); - } - - // if any of the selected areas (any pane) is resource-defined then check to make sure - // it is still available and if not reset to the given rsc or the default if null. - // return true if an area was changed. - // - public Boolean checkAndUpdateAreaFromResource( ResourceSelection rscSel ) { + maxLayout = maxPaneLayout; + init(dispType); + } - // get a map of all of the currently selected areas - // - Map seldAreaNames = new HashMap(); - - // if geoSynced then there will be only one selected area and if - // it is reset then it will be reset for all panes. - if( isGeoSyncPanes() ) { - - PredefinedArea seldArea = getSelectedArea(); - seldAreaNames.put( getSelectedPaneId().toString(), - new AreaName( seldArea.getSource(), seldArea.getAreaName() ) ); - } - else { - seldAreaNames = getAllSelectedAreaNames(); - } - - // determine what to reset an area to - Boolean areaChanged = false; - AreaName resetAreaName; + // the maximum number of rows & columns + private NcPaneLayout maxLayout = new NcPaneLayout(6, 6); - // all available resource defined areas (from all panes) - List availRscAreas = getResourceProvidedAreas(); + // an RBD must be one of these display types and all resources in the RBD + // must be compatible + // with the display type. + private NcDisplayType rbdType; - if( rscSel != null && - rscSel.getResourceData() instanceof IAreaProviderCapable ) { + // the currently selected layout (numRows,numColumns) + private INcPaneLayout currRbdPaneLayout = new NcPaneLayout(1, 1); - // NOTE : assume that the rscSel is valid. Dont need to check that - // it is in the availRscAreas list. - IAreaProviderCapable aProv = (IAreaProviderCapable)rscSel.getResourceData(); - resetAreaName = new AreaName( aProv.getSourceProvider(), aProv.getAreaName() ); - - // if replaceing a rsc-defined area with another in a single pane or - // in a geo-synced multipane then go ahead and replace the area - // - if( !isMultiPane() || isGeoSyncPanes() ) { - if( seldAreaNames.get( getSelectedPaneId().toString() ).getSource().isImagedBased() ) { - try { - setSelectedAreaName( resetAreaName ); - return true; - } catch (VizException e) { - System.out.println("Error reseting area??? : "+e.getMessage() ); - return false; - } - } - } - } - else { - resetAreaName = new AreaName( AreaSource.PREDEFINED_AREA, rbdType.getDefaultMap() ); - } + // the currently selected pane + private NcPaneID selectedPaneId = new NcPaneID(); // 0,0 - // loop thru the panes and check for resource-defined areas - for( String paneIdStr : seldAreaNames.keySet() ) { - AreaName areaName = seldAreaNames.get( paneIdStr ); + // this will map the paneID (as a string) to the current area and resource + // information . Note : use a String since the paneIndex is relative to the + // selected paneLayout which may change. + private HashMap paneSelectionDataMap = new HashMap(); - if( !areaName.getSource().isImagedBased() ) { - continue; - } - - Boolean areaRscIsAvailable = false; - - for( AreaMenuItem ami : availRscAreas ) { - // if we have found the resource for the given area - // then continue to the next pane - if( AreaSource.getAreaSource( ami.getSource()) == areaName.getSource() && - ami.getAreaName().equals( areaName.getName() ) ) { - areaRscIsAvailable = true; - break; - } - } - - if( areaRscIsAvailable ) { - continue; - } - - // reset this pane's area to either the default or to the given rsc (ie a replace. - // note : if geosync is set then this will reset all of the areas - // - try { - INcPaneID curPid = getSelectedPaneId(); - setSelectedPaneId( NcPaneID.parsePaneId( paneIdStr ) ); - - setSelectedAreaName( resetAreaName ); - - setSelectedPaneId( curPid ); - - areaChanged = true; + // the entry in the paneSelectionDataMap that is currently selected + private PaneSelectionData selectedPaneData = null; - } - catch (VizException e) { - System.out.println("Error resetting area to "+resetAreaName.toString()+ - ": "+ e.getMessage() ); - } - } - - return areaChanged; - } - - // return - public List> getAvailAreaMenuItems() { - List> areaMenuItems = new ArrayList>(); - AreaMenuItem ami, seldami, dfltami; - List amiList; - AreaName areaName; - - // ?? create area factories for NTRANS and SOLAR (just one 'default' area for now...) - if( rbdType == NcDisplayType.NTRANS_DISPLAY || - rbdType == NcDisplayType.SOLAR_DISPLAY ) { - areaMenuItems.add( new ArrayList() ); - areaMenuItems.get(0).add( - new AreaMenuItem( new AreaName( AreaSource.PREDEFINED_AREA, rbdType.getDefaultMap() ) ) ); - return areaMenuItems; - } + // base resources can't be removed and are the same instance for all panes. + // ie. the geopolitical overlay. + private static Map baseOverlayResources = new HashMap(); - // first is the selected area (not in a submenu) - amiList = new ArrayList(); - areaName = new AreaName( getSelectedArea().getSource(), getSelectedArea().getAreaName() ); - - if( areaName.getSource() == AreaSource.INITIAL_DISPLAY_AREA ) { - seldami = new AreaMenuItem( "Custom", "", areaName.getName(), areaName.getSource().toString() ); - } - else { - seldami = new AreaMenuItem( areaName ); - } + private boolean geoSyncPanes = false; - amiList.add( seldami ); - areaMenuItems.add( amiList ); + private boolean autoUpdate = false; - amiList = new ArrayList(); + private boolean multiPane = false; - // if the initial area is custom and not seleced then add it since it won't be saved - // - PredefinedArea initArea = selectedPaneData.getInitialArea(); - if( initArea != null && initArea != getSelectedArea() && - initArea.getSource() == AreaSource.INITIAL_DISPLAY_AREA ) { + private String rbdName = ""; - seldami = new AreaMenuItem( "Custom", "", - initArea.getAreaName(), initArea.getSource().toString() ); - amiList.add( seldami ); - areaMenuItems.add( amiList ); - } - - // the default next if its not selected. - if( getSelectedArea().getAreaName().equals( rbdType.getDefaultMap() ) ) { - dfltami = seldami; - } - else { - amiList = new ArrayList(); - areaName = new AreaName( AreaSource.PREDEFINED_AREA, rbdType.getDefaultMap() ); - dfltami = new AreaMenuItem( areaName ); - amiList.add( dfltami ); - areaMenuItems.add( amiList ); - } - - // next areas from the current display (if multipane then put in a submenu) - amiList = new ArrayList(); - AbstractEditor ed = NcDisplayMngr.getActiveNatlCntrsEditor(); - - if( ed != null && NcEditorUtil.getNcDisplayType( ed ) == rbdType ) { - IDisplayPane[] panes = ( NcEditorUtil.arePanesGeoSynced( ed ) ? - NcEditorUtil.getSelectedPanes(ed) : ed.getDisplayPanes() ); + // set to true here if any of the resources, currRbdPaneLayout,... is + // changed. Reset to false here + // if initialized. Set to true from the dialog if a resource is edited or if + // the rbd is cleared. + private boolean rbdModified = false; - for( IDisplayPane pane : panes ) { - if( pane.getRenderableDisplay() instanceof IAreaProviderCapable ) { - IAreaProviderCapable aPrv = (IAreaProviderCapable)pane.getRenderableDisplay(); - - ami = new AreaMenuItem( aPrv.getAreaName(), - (panes.length > 1 ? "Display" : ""), aPrv.getAreaName(), aPrv.getSourceProvider().toString() ); - - amiList.add( ami ); - } - } - } - - if( !amiList.isEmpty() ) { - areaMenuItems.add( amiList ); - } + // the initial timeMatcher from an AbstractRBD. This may be superceded by + // any changes from the GUI. + private NCTimeMatcher initialTimeMatcher = null; - // next are any area provided by a selected resource. - // TODO : put these in submenus based on the resource type - //for( String rscType : new String[]{ "MCIDAS", "GINI" } ) { - // then any possible area-capable resources - amiList = getResourceProvidedAreas(); //new ArrayList(); - - if( !amiList.isEmpty() ) { - areaMenuItems.add( amiList ); - } + public NcPaneLayout getMaxPaneLayout() { + return maxLayout; + } - // finally add the areas from the areaMenus file. - Map> areaMenusMap = AreaMenusMngr.getInstance().getPredefinedAreasForMenus(); + public boolean isRbdModified() { + return rbdModified; + } - for( List alst : areaMenusMap.values() ) { - if( alst == null || alst.isEmpty() || - alst.get(0).getSubMenuName().isEmpty() ) { - continue; - } - areaMenuItems.add( alst ); - } - - amiList = new ArrayList(); - - if( areaMenusMap.containsKey("") ) { - for( AreaMenuItem i : areaMenusMap.get( "" ) ) { - if( !seldami.equals( i ) && - !dfltami.equals( i ) ) { - amiList.add( i ); - } - } - } - - if( !amiList.isEmpty() ) { - areaMenuItems.add( amiList ); - } + public void setRbdModified(boolean rbdModified) { + this.rbdModified = rbdModified; + } - return areaMenuItems; - } - - // get a list of all available areas resource-defined areas - // Called by getAvailAreaMenuItems and used to determine if - // an area is still avail afer a resource has been removed or replaced. - // - public List getResourceProvidedAreas() { - List amiList = new ArrayList(); - - for( int paneIndx=0 ; paneIndx(); -// areaMenuItems.put( areaRsc.getSourceProvider().toString(), rscItems ); -// } - - if( !amiList.contains( ami ) ) { - amiList.add( ami ); - } - } - } - } - return amiList; - } - - public boolean addSelectedResource( ResourceSelection rsel ) { - if( !Arrays.asList( rsel.getSupportedDisplayTypes() ).contains( rbdType ) ) { - System.out.println("??Can't add resource "+rsel.getRscLabel()+" because it is not"+ - " supported for display type "+rbdType.getName() ); - return false; - } + this.multiPane = multiPane; + } - rbdModified = true; + // note that if multipane is false then only the 1,1 pane will be used + public INcPaneLayout getPaneLayout() { + return currRbdPaneLayout; + } - boolean retval = selectedPaneData.addSelectedResource( rsel ); - - return retval; - - } - - public boolean addSelectedResourceToAllPanes( ResourceSelection rbt ) { - for( PaneSelectionData paneData : paneSelectionDataMap.values() ) { - paneData.addSelectedResource( rbt ); - } - rbdModified = true; - - return true; - } + // return the selected paneId so the caller may tell if it changed. + public INcPaneID setPaneLayout(INcPaneLayout paneLayout) { + if (this.currRbdPaneLayout.equals(paneLayout)) { + return selectedPaneId; + } - public boolean replaceSelectedResource( ResourceSelection existingRsc, ResourceSelection newRsc ) { - if( !Arrays.asList( newRsc.getSupportedDisplayTypes() ).contains( rbdType ) ) { - System.out.println("??Can't add resource "+newRsc.getRscLabel()+" because it is not"+ - " supported for display type "+rbdType.getName() ); - return false; - } - - rbdModified = true; - boolean retval = selectedPaneData.replaceSelectedResource( existingRsc, newRsc ); - - checkAndUpdateAreaFromResource( newRsc ); - - return retval; - } + rbdModified = true; + + // if( paneLayout.getRows() <= selectedPaneId.getRow() ) { + // selectedPaneId = new NcPaneID( selectedPaneId.getRow()-1, + // selectedPaneId.getColumn() ); + // } + // if( paneLayout.getColumns() <= selectedPaneId.getColumn() ) { + // selectedPaneId = new NcPaneID( selectedPaneId.getRow(), + // selectedPaneId.getColumn()-1 ); + // } + if (!paneLayout.containsPaneId(selectedPaneId)) { + selectedPaneId = new NcPaneID(); + } + + currRbdPaneLayout = paneLayout; + + setMultiPane(paneLayout.getNumberOfPanes() > 1); + + // // make sure there is an entry in the map for each pane + // for( int p=0 ; p rbdBndl) + throws VizException { + + // reset all panes and then set the PaneData for those in the rbd. + init(rbdBndl.getDisplayType()); + + // TODO : don't set the rbdName if it is the default RBD as a + setRbdType(rbdBndl.getDisplayType()); + setRbdName(rbdBndl.getRbdName()); + setPaneLayout(rbdBndl.getPaneLayout()); + setAutoUpdate(rbdBndl.isAutoUpdate()); + setGeoSyncPanes(rbdBndl.isGeoSyncedPanes()); + + // loop through each of the panes and initialize the paneData to the + // selections in the rbd. + for (int paneIndx = 0; paneIndx < currRbdPaneLayout.getNumberOfPanes(); paneIndx++) { + INcPaneID paneId = currRbdPaneLayout.createPaneId(paneIndx); + + setSelectedPaneId(paneId); + + INatlCntrsRenderableDisplay dispPane = rbdBndl + .getDisplayPane(paneId); + + setPaneData(dispPane); + } + + setSelectedPaneId(rbdBndl.getSelectedPaneId()); + + if (rbdBndl.getTimeMatcher() == null) { + initialTimeMatcher = new NCTimeMatcher(); + } else { + initialTimeMatcher = rbdBndl.getTimeMatcher(); + } + + rbdModified = false; + + return true; + } + + // used when importing a single pane. In this case the display-defined + // area has not been added as an available selection. + // + public void setPaneData(INatlCntrsRenderableDisplay dispPane) + throws VizException { + + // NOTE: the currently selected paneId doesn't have to match the + // dispPane's paneId. + // + + // loop through the resources and add them + for (ResourcePair rp : dispPane.getDescriptor().getResourceList()) { + if (rp.getResourceData() instanceof INatlCntrsResourceData) { + try { + ResourceSelection rscSel = ResourceFactory + .createResource(rp); + + addSelectedResource(rscSel); + + if (rscSel.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData) { + // timelineControl.addAvailDomResource( + // (AbstractNatlCntrsRequestableResourceData) + // rbt.getResourceData() ); + } + } catch (VizException ve) { + System.out.println("Unable to add selected Resource:" + + ((INatlCntrsResourceData) rp.getResourceData()) + .getResourceName().toString()); + continue; + } + + } else if (!rp.getProperties().isSystemResource()) { + System.out.println("Unable to load non-NC non-System Resource:" + + rp.getResourceData().toString()); + } + } + + // how to set size-of-image if the imported zoom level is not -1? we + // can't even tell if + // it has been changed from the original size-of-image??? + // + + // set the selected areaname from the display using the following rules. + // if this is from a current editor display and the current area has + // been changed from the initial area + // that the display was loaded with then the selected area will be the + // current area of the display + // (the source is DISPLAY_AREA and the areaname is the name of the + // display pane) + // if from a current editor and the current and initial areas are the + // same then use the + // name of the area initially used to load the display. + // if this display pane is imported from and RBD then the initial area + // and the current area + // should be the same. + // AreaName seldAreaName = new AreaName( AreaSource.PREDEFINED_AREA, + // rbdType.getDefaultMap() ); + + PredefinedArea initialArea = dispPane.getInitialArea(); + + // AreaName seldAreaName = new AreaName( initialArea.getSource(), + // initialArea.getAreaName() ); + PredefinedArea seldPredefinedArea = initialArea; + + // if the display's current area is different than its initial area then + // set the display as the selected area otherwise use the name of the + // area + // originally used to set the display's area. + NcDisplayName dispName = dispPane.getPaneName().getDispName(); + + if (dispName.getId() > 0 && // dispPane.getPaneManager() instanceof + // NCPaneManager && + dispPane instanceof IAreaProviderCapable) { + + // the name of the display's area will be the name of the pane. + AreaName currDispAreaName = new AreaName(AreaSource.DISPLAY_AREA, + ((IAreaProviderCapable) dispPane).getAreaName()); + try { + IGridGeometryProvider currGeom = NcAreaProviderMngr + .createGeomProvider(currDispAreaName); + + // the name of the selected area will be the current area of the + // imported display + // unless the area has not been changed and the initial area is + // a predefined area + if (currGeom != null && initialArea != null) { // sanity check + + PredefinedArea currArea = PredefinedAreaFactory + .createPredefinedArea(currGeom); + + // The areAreasEqual method doesn't work on SizeOfImage. + // This will lock the zoom + // so we will assume that if the initial area is SizeOfImage + // that the initial area + // is the + if (!initialArea.getZoomLevel().equals( + ZoomLevelStrings.SizeOfImage.toString()) + && !initialArea.getZoomLevel().equals( + ZoomLevelStrings.FitToScreen.toString())) { + + // use the area of the current display if the areas are + // different + // or if the same but the initial area is not a + // named/saved area name. + // + if (PredefinedArea.areAreasEqual(initialArea, currArea)) { + if (initialArea.getSource() == AreaSource.INITIAL_DISPLAY_AREA) { + // seldAreaName = currDispAreaName; + seldPredefinedArea = currArea; + } + } else { + // seldAreaName = currDispAreaName; + seldPredefinedArea = currArea; + } + } + } + } catch (VizException ve) { + System.out.println("error getting curr area for " + + dispPane.getPaneName()); + } + } + + try { + setSelectedArea(seldPredefinedArea); + } catch (VizException ve) { + setSelectedAreaName(new AreaName(AreaSource.PREDEFINED_AREA, + rbdType.getDefaultMap())); + } + + // setSelectedPaneId( paneId ); + } + + public ResourceSelection[] getSelectedRscs() { + return selectedPaneData.getSelectedResources(); + } + + public ResourceSelection[] getRscsForPane(INcPaneID paneId) { + if (!paneSelectionDataMap.containsKey(paneId.toString())) { + return new ResourceSelection[] {}; + } + return paneSelectionDataMap.get(paneId.toString()) + .getSelectedResources(); + } + + // if any of the selected areas (any pane) is resource-defined then check to + // make sure + // it is still available and if not reset to the given rsc or the default if + // null. + // return true if an area was changed. + // + public Boolean checkAndUpdateAreaFromResource(ResourceSelection rscSel) { + + // get a map of all of the currently selected areas + // + Map seldAreaNames = new HashMap(); + + // if geoSynced then there will be only one selected area and if + // it is reset then it will be reset for all panes. + if (isGeoSyncPanes()) { + + PredefinedArea seldArea = getSelectedArea(); + seldAreaNames.put(getSelectedPaneId().toString(), new AreaName( + seldArea.getSource(), seldArea.getAreaName())); + } else { + seldAreaNames = getAllSelectedAreaNames(); + } + + // determine what to reset an area to + Boolean areaChanged = false; + AreaName resetAreaName; + + // all available resource defined areas (from all panes) + List availRscAreas = getResourceProvidedAreas(); + + if (rscSel != null + && rscSel.getResourceData() instanceof IAreaProviderCapable) { + + // NOTE : assume that the rscSel is valid. Dont need to check that + // it is in the availRscAreas list. + IAreaProviderCapable aProv = (IAreaProviderCapable) rscSel + .getResourceData(); + resetAreaName = new AreaName(aProv.getSourceProvider(), + aProv.getAreaName()); + + // if replaceing a rsc-defined area with another in a single pane or + // in a geo-synced multipane then go ahead and replace the area + // + if (!isMultiPane() || isGeoSyncPanes()) { + if (seldAreaNames.get(getSelectedPaneId().toString()) + .getSource().isImagedBased()) { + try { + setSelectedAreaName(resetAreaName); + return true; + } catch (VizException e) { + System.out.println("Error reseting area??? : " + + e.getMessage()); + return false; + } + } + } + } else { + resetAreaName = new AreaName(AreaSource.PREDEFINED_AREA, + rbdType.getDefaultMap()); + } + + // loop thru the panes and check for resource-defined areas + for (String paneIdStr : seldAreaNames.keySet()) { + AreaName areaName = seldAreaNames.get(paneIdStr); + + if (!areaName.getSource().isImagedBased()) { + continue; + } + + Boolean areaRscIsAvailable = false; + + for (AreaMenuItem ami : availRscAreas) { + // if we have found the resource for the given area + // then continue to the next pane + if (AreaSource.getAreaSource(ami.getSource()) == areaName + .getSource() + && ami.getAreaName().equals(areaName.getName())) { + areaRscIsAvailable = true; + break; + } + } + + if (areaRscIsAvailable) { + continue; + } + + // reset this pane's area to either the default or to the given rsc + // (ie a replace. + // note : if geosync is set then this will reset all of the areas + // + try { + INcPaneID curPid = getSelectedPaneId(); + setSelectedPaneId(NcPaneID.parsePaneId(paneIdStr)); + + setSelectedAreaName(resetAreaName); + + setSelectedPaneId(curPid); + + areaChanged = true; + + } catch (VizException e) { + System.out.println("Error resetting area to " + + resetAreaName.toString() + ": " + e.getMessage()); + } + } + + return areaChanged; + } + + // return + public List> getAvailAreaMenuItems() { + List> areaMenuItems = new ArrayList>(); + AreaMenuItem ami, seldami, dfltami; + List amiList; + AreaName areaName; + + // ?? create area factories for NTRANS and SOLAR (just one 'default' + // area for now...) + if (rbdType == NcDisplayType.NTRANS_DISPLAY + || rbdType == NcDisplayType.SOLAR_DISPLAY + || rbdType == NcDisplayType.GRAPH_DISPLAY) { + areaMenuItems.add(new ArrayList()); + areaMenuItems.get(0).add( + new AreaMenuItem(new AreaName(AreaSource.PREDEFINED_AREA, + rbdType.getDefaultMap()))); + return areaMenuItems; + } + + // first is the selected area (not in a submenu) + amiList = new ArrayList(); + areaName = new AreaName(getSelectedArea().getSource(), + getSelectedArea().getAreaName()); + + if (areaName.getSource() == AreaSource.INITIAL_DISPLAY_AREA) { + seldami = new AreaMenuItem("Custom", "", areaName.getName(), + areaName.getSource().toString()); + } else { + seldami = new AreaMenuItem(areaName); + } + + amiList.add(seldami); + areaMenuItems.add(amiList); + + amiList = new ArrayList(); + + // if the initial area is custom and not seleced then add it since it + // won't be saved + // + PredefinedArea initArea = selectedPaneData.getInitialArea(); + if (initArea != null && initArea != getSelectedArea() + && initArea.getSource() == AreaSource.INITIAL_DISPLAY_AREA) { + + seldami = new AreaMenuItem("Custom", "", initArea.getAreaName(), + initArea.getSource().toString()); + amiList.add(seldami); + areaMenuItems.add(amiList); + } + + // the default next if its not selected. + if (getSelectedArea().getAreaName().equals(rbdType.getDefaultMap())) { + dfltami = seldami; + } else { + amiList = new ArrayList(); + areaName = new AreaName(AreaSource.PREDEFINED_AREA, + rbdType.getDefaultMap()); + dfltami = new AreaMenuItem(areaName); + amiList.add(dfltami); + areaMenuItems.add(amiList); + } + + // next areas from the current display (if multipane then put in a + // submenu) + amiList = new ArrayList(); + AbstractEditor ed = NcDisplayMngr.getActiveNatlCntrsEditor(); + + if (ed != null && NcEditorUtil.getNcDisplayType(ed) == rbdType) { + IDisplayPane[] panes = (NcEditorUtil.arePanesGeoSynced(ed) ? NcEditorUtil + .getSelectedPanes(ed) : ed.getDisplayPanes()); + + for (IDisplayPane pane : panes) { + if (pane.getRenderableDisplay() instanceof IAreaProviderCapable) { + IAreaProviderCapable aPrv = (IAreaProviderCapable) pane + .getRenderableDisplay(); + + ami = new AreaMenuItem(aPrv.getAreaName(), + (panes.length > 1 ? "Display" : ""), + aPrv.getAreaName(), aPrv.getSourceProvider() + .toString()); + + amiList.add(ami); + } + } + } + + if (!amiList.isEmpty()) { + areaMenuItems.add(amiList); + } + + // next are any area provided by a selected resource. + // TODO : put these in submenus based on the resource type + // for( String rscType : new String[]{ "MCIDAS", "GINI" } ) { + // then any possible area-capable resources + amiList = getResourceProvidedAreas(); // new ArrayList(); + + if (!amiList.isEmpty()) { + areaMenuItems.add(amiList); + } + + // finally add the areas from the areaMenus file. + Map> areaMenusMap = AreaMenusMngr + .getInstance().getPredefinedAreasForMenus(); + + for (List alst : areaMenusMap.values()) { + if (alst == null || alst.isEmpty() + || alst.get(0).getSubMenuName().isEmpty()) { + continue; + } + areaMenuItems.add(alst); + } + + amiList = new ArrayList(); + + if (areaMenusMap.containsKey("")) { + for (AreaMenuItem i : areaMenusMap.get("")) { + if (!seldami.equals(i) && !dfltami.equals(i)) { + amiList.add(i); + } + } + } + + if (!amiList.isEmpty()) { + areaMenuItems.add(amiList); + } + + return areaMenuItems; + } + + // get a list of all available areas resource-defined areas + // Called by getAvailAreaMenuItems and used to determine if + // an area is still avail afer a resource has been removed or replaced. + // + public List getResourceProvidedAreas() { + List amiList = new ArrayList(); + + for (int paneIndx = 0; paneIndx < currRbdPaneLayout.getNumberOfPanes(); paneIndx++) { + PaneSelectionData paneData = paneSelectionDataMap + .get(currRbdPaneLayout.createPaneId(paneIndx).toString()); + + for (ResourceSelection rscSel : paneData.getSelectedResources()) { + if (rscSel.getResourceData() instanceof IAreaProviderCapable) { + + IAreaProviderCapable areaRsc = (IAreaProviderCapable) rscSel + .getResourceData(); + + AreaName areaName = new AreaName( + areaRsc.getSourceProvider(), areaRsc.getAreaName()); + // ami = new AreaMenuItem( areaName ); + AreaMenuItem ami = new AreaMenuItem(areaRsc.getAreaName(), + "Resource", areaRsc.getAreaName(), areaRsc + .getSourceProvider().toString()); + + // use the source name as the sub menu name + // if( rscItems == null ) { + // rscItems = new ArrayList(); + // areaMenuItems.put( + // areaRsc.getSourceProvider().toString(), rscItems ); + // } + + if (!amiList.contains(ami)) { + amiList.add(ami); + } + } + } + } + return amiList; + } + + public boolean addSelectedResource(ResourceSelection rsel) { + NcDisplayType[] type = rsel.getSupportedDisplayTypes(); + if (!Arrays.asList(rsel.getSupportedDisplayTypes()).contains(rbdType)) { + System.out.println("??Can't add resource " + rsel.getRscLabel() + + " because it is not" + " supported for display type " + + rbdType.getName()); + return false; + } + + rbdModified = true; + + boolean retval = selectedPaneData.addSelectedResource(rsel); + + return retval; + + } + + public boolean addSelectedResourceToAllPanes(ResourceSelection rbt) { + for (PaneSelectionData paneData : paneSelectionDataMap.values()) { + paneData.addSelectedResource(rbt); + } + rbdModified = true; + + return true; + } + + public boolean replaceSelectedResource(ResourceSelection existingRsc, + ResourceSelection newRsc) { + if (!Arrays.asList(newRsc.getSupportedDisplayTypes()).contains(rbdType)) { + System.out.println("??Can't add resource " + newRsc.getRscLabel() + + " because it is not" + " supported for display type " + + rbdType.getName()); + return false; + } + + rbdModified = true; + boolean retval = selectedPaneData.replaceSelectedResource(existingRsc, + newRsc); + + checkAndUpdateAreaFromResource(newRsc); + + return retval; + } + + public void removeSelectedResource(ResourceSelection rbt) { + rbdModified = true; + selectedPaneData.removeSelectedResource(rbt); + checkAndUpdateAreaFromResource(null); + } + + public void removeAllSelectedResources() { + rbdModified = true; + selectedPaneData.removeSelectedResource(null); + + checkAndUpdateAreaFromResource(null); + } + + // public void removeAllSelectedResourcesForPane( INcPaneID paneId ) { + // if( !paneSelectionDataMap.containsKey( paneId.toString() ) ) { + // return; + // } + // rbdModified = true; + // PaneSelectionData psd = paneSelectionDataMap.get( paneId.toString() ); + // for( ResourceSelection rs : psd.getSelectedResources() ) { + // removeAvailAreaProvider( rs ); + // psd.removeSelectedResource( rs ); + // } + // } - public void removeSelectedResource( ResourceSelection rbt ) { - rbdModified = true; - selectedPaneData.removeSelectedResource( rbt ); - checkAndUpdateAreaFromResource( null ); - } - - public void removeAllSelectedResources( ) { - rbdModified = true; - selectedPaneData.removeSelectedResource( null ); - - checkAndUpdateAreaFromResource( null ); - } - -// public void removeAllSelectedResourcesForPane( INcPaneID paneId ) { -// if( !paneSelectionDataMap.containsKey( paneId.toString() ) ) { -// return; -// } -// rbdModified = true; -// PaneSelectionData psd = paneSelectionDataMap.get( paneId.toString() ); -// for( ResourceSelection rs : psd.getSelectedResources() ) { -// removeAvailAreaProvider( rs ); -// psd.removeSelectedResource( rs ); -// } -// } - - public NcDisplayType getRbdType() { - return rbdType; - } + return rbdType; + } - public void setRbdType(NcDisplayType rbdType) { - this.rbdType = rbdType; - } + public void setRbdType(NcDisplayType rbdType) { + this.rbdType = rbdType; + } -// public ResourceSelection getBaseOverlay( ) { -// return baseOverlayRBT; -// } - - public PredefinedArea getSelectedArea() { - return selectedPaneData.getArea();//.getAreaName();//GeoAreaName(); - } - - // return a map of all the currently selected areanames (with pane id as the key) - public Map getAllSelectedAreaNames() { - Map areasMap = new HashMap(); - for( int paneIndx=0 ; paneIndx getAllSelectedAreaNames() { + Map areasMap = new HashMap(); + for (int paneIndx = 0; paneIndx < currRbdPaneLayout.getNumberOfPanes(); paneIndx++) { + NcPaneID paneId = (NcPaneID) currRbdPaneLayout + .createPaneId(paneIndx); - public void setZoomLevel( String zl ) { - if( isMultiPane() && isGeoSyncPanes() ) { - for( PaneSelectionData paneData : paneSelectionDataMap.values() ) { - paneData.setZoomLevel( zl ); - } - } - else { - selectedPaneData.setZoomLevel( zl ); - } + PaneSelectionData psd = paneSelectionDataMap.get(paneId.toString()); + areasMap.put(paneId.toString(), new AreaName(psd.getArea() + .getSource(), psd.getArea().getAreaName())); + } + return areasMap; + } - } + // called when initializing the pane data + // If multi-pane and if geoSync is set then we will need to update all of + // the panes + public void setSelectedArea(PredefinedArea seldArea) throws VizException { + rbdModified = true; + + if (isMultiPane() && isGeoSyncPanes()) { + for (PaneSelectionData paneData : paneSelectionDataMap.values()) { + paneData.setArea(seldArea); + } + } else { + selectedPaneData.setArea(seldArea); + } + + } + + // called from the GUI + public void setSelectedAreaName(AreaName areaName) throws VizException { + + // if Custom then use null as a flag to reset to the saved initial area + if (areaName.getSource() == AreaSource.INITIAL_DISPLAY_AREA) { + setSelectedArea(null); + } else { + IGridGeometryProvider geom = NcAreaProviderMngr + .createGeomProvider(areaName); + PredefinedArea seldArea = PredefinedAreaFactory + .createPredefinedArea(geom); + if (seldArea == null) { + throw new VizException("Unable to set the Area to " + + areaName.toString()); + } + + setSelectedArea(seldArea); + } + } + + public void setZoomLevel(String zl) { + if (isMultiPane() && isGeoSyncPanes()) { + for (PaneSelectionData paneData : paneSelectionDataMap.values()) { + paneData.setZoomLevel(zl); + } + } else { + selectedPaneData.setZoomLevel(zl); + } + + } + + // update all of the geoAreaNames to the area in the current pane + // Include hidden panes too in case the user expands the number of panes, + // the area will be set correctly + // + public void syncPanesToArea() { + setGeoSyncPanes(true); + PredefinedArea seldArea = getSelectedArea(); + + for (PaneSelectionData psd : paneSelectionDataMap.values()) { + psd.setArea(seldArea); + } + + rbdModified = true; + } - // update all of the geoAreaNames to the area in the current pane - // Include hidden panes too in case the user expands the number of panes, - // the area will be set correctly - // - public void syncPanesToArea( ) { - setGeoSyncPanes( true ); - PredefinedArea seldArea = getSelectedArea(); - - for( PaneSelectionData psd : paneSelectionDataMap.values() ) { - psd.setArea( seldArea ); - } - - rbdModified = true; - } - public boolean isGeoSyncPanes() { - return geoSyncPanes; - } + return geoSyncPanes; + } - public void setGeoSyncPanes(boolean geoSyncPanes) { - this.geoSyncPanes = geoSyncPanes; - } - - public boolean isAutoUpdate() { - return autoUpdate; - } + public void setGeoSyncPanes(boolean geoSyncPanes) { + this.geoSyncPanes = geoSyncPanes; + } - public void setAutoUpdate(boolean autoUpdate) { - if( this.autoUpdate == autoUpdate ) { - return; - } + public boolean isAutoUpdate() { + return autoUpdate; + } - rbdModified = true; - - this.autoUpdate = autoUpdate; - } - - public NCTimeMatcher getInitialTimeMatcher() { - return initialTimeMatcher; - } + public void setAutoUpdate(boolean autoUpdate) { + if (this.autoUpdate == autoUpdate) { + return; + } - // Create the RBD - // get the resources, overlays and map background bundle files. Load each bundle and re-bundle - // them into an RBD bundle file. - // - public AbstractRBD createRbdBundle( String rbdName, NCTimeMatcher timeMatcher ) throws VizException { - - NcPaneLayout rbdPaneLayout = new NcPaneLayout(1,1); + rbdModified = true; - if( isMultiPane() ) { - rbdPaneLayout = new NcPaneLayout( - ((NcPaneLayout)currRbdPaneLayout).getRows(), - ((NcPaneLayout)currRbdPaneLayout).getColumns() ); - } - - AbstractRBD rbdBndl = AbstractRBD.createEmptyRbdForDisplayType( rbdType, rbdPaneLayout ); - if( rbdBndl == null ) { - throw new VizException("Unsupported RBD type"); - } - - rbdBndl.setRbdName( rbdName ); -// rbdBndl.setPaneLayout( (NcPaneLayout)getPaneLayout() ); - - if( timeMatcher != null ) { - rbdBndl.setTimeMatcher( timeMatcher ); - } - - rbdBndl.setSelectedPaneId( (isMultiPane() ? selectedPaneId : new NcPaneID()) ); - - rbdBndl.setAutoUpdate( autoUpdate ); - rbdBndl.setGeoSyncedPanes( geoSyncPanes ); - - for( int paneIndx=0 ; paneIndx and is also set for each descriptor - descr.setAutoUpdate( autoUpdate ); - - if( descr.getResourceList() == null ) { - VizException ve = new VizException( "getResourceList is null??." ); - throw ve; - } - else { - descr.getResourceList().clear(); - } + // Create the RBD + // get the resources, overlays and map background bundle files. Load each + // bundle and re-bundle + // them into an RBD bundle file. + // + public AbstractRBD createRbdBundle(String rbdName, + NCTimeMatcher timeMatcher) throws VizException { - // loop thru the bundles for the selected rscs - // - for( ResourceSelection rbt : paneData.getSelectedResources() ) { - ResourcePair rscPair = rbt.getResourcePair(); -// if( dfltDomRscName == null && -// rscPair.getResourceData() instanceof AbstractNatlCntrsRequestableResourceData ) { -// dfltDomRscName = ((INatlCntrsResourceData) -// rscPair.getResourceData()).getFullResourceName(); -// } -// if( rbt.isDominant() ) { -// selDomRsc = (AbstractNatlCntrsRequestableResourceData) rscPair.getResourceData(); -// } - descr.getResourceList().add( rscPair ); - } - - // set the timeMatcher for the Descriptor (This will be the same timeMatcher - // for all panes. - descr.setTimeMatcher( timeMatcher ); - -// rbdBndl.addDisplayPane( dispPane, paneId ); - } - - rbdBndl.setIsDefaultRbd( false ); - - return rbdBndl; - } + NcPaneLayout rbdPaneLayout = new NcPaneLayout(1, 1); + + if (isMultiPane()) { + rbdPaneLayout = new NcPaneLayout( + ((NcPaneLayout) currRbdPaneLayout).getRows(), + ((NcPaneLayout) currRbdPaneLayout).getColumns()); + } + + AbstractRBD rbdBndl = AbstractRBD.createEmptyRbdForDisplayType( + rbdType, rbdPaneLayout); + if (rbdBndl == null) { + throw new VizException("Unsupported RBD type"); + } + + rbdBndl.setRbdName(rbdName); + // rbdBndl.setPaneLayout( (NcPaneLayout)getPaneLayout() ); + + if (timeMatcher != null) { + rbdBndl.setTimeMatcher(timeMatcher); + } + + rbdBndl.setSelectedPaneId((isMultiPane() ? selectedPaneId + : new NcPaneID())); + + rbdBndl.setAutoUpdate(autoUpdate); + rbdBndl.setGeoSyncedPanes(geoSyncPanes); + + for (int paneIndx = 0; paneIndx < rbdPaneLayout.getNumberOfPanes(); paneIndx++) { + NcPaneID paneId = (NcPaneID) rbdPaneLayout.createPaneId(paneIndx); + + PaneSelectionData paneData = paneSelectionDataMap.get(paneId + .toString()); + + PredefinedArea pArea = paneData.getArea(); + + // + if (pArea.getSource() == AreaSource.DISPLAY_AREA) { + pArea.setAreaSource(AreaSource.INITIAL_DISPLAY_AREA.toString()); + pArea.setAreaName(rbdName); + } + + INatlCntrsRenderableDisplay iNcRendDisp = rbdBndl + .getDisplayPane(paneId); + + iNcRendDisp.setInitialArea(pArea); + + INatlCntrsDescriptor descr = (INatlCntrsDescriptor) iNcRendDisp + .getDescriptor(); + + // auto update is set for the AbstractRBD and is also set for + // each descriptor + descr.setAutoUpdate(autoUpdate); + + if (descr.getResourceList() == null) { + VizException ve = new VizException("getResourceList is null??."); + throw ve; + } else { + descr.getResourceList().clear(); + } + + // loop thru the bundles for the selected rscs + // + for (ResourceSelection rbt : paneData.getSelectedResources()) { + ResourcePair rscPair = rbt.getResourcePair(); + // if( dfltDomRscName == null && + // rscPair.getResourceData() instanceof + // AbstractNatlCntrsRequestableResourceData ) { + // dfltDomRscName = ((INatlCntrsResourceData) + // rscPair.getResourceData()).getFullResourceName(); + // } + // if( rbt.isDominant() ) { + // selDomRsc = (AbstractNatlCntrsRequestableResourceData) + // rscPair.getResourceData(); + // } + descr.getResourceList().add(rscPair); + } + + // set the timeMatcher for the Descriptor (This will be the same + // timeMatcher + // for all panes. + descr.setTimeMatcher(timeMatcher); + + // rbdBndl.addDisplayPane( dispPane, paneId ); + } + + rbdBndl.setIsDefaultRbd(false); + + return rbdBndl; + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/GraphTimelineUtil.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/GraphTimelineUtil.java new file mode 100644 index 0000000000..dc981fcbfa --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/GraphTimelineUtil.java @@ -0,0 +1,159 @@ +package gov.noaa.nws.ncep.viz.resources.time_match; + +/** + * Time matching for Natl Cntrs is based on the dominant source. The data times + * defined by it are the times for all of the resources. Other resources will + * need to time match their data to this list of data times. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 05/02/14     #1131      qzhou    Initial creation
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + */ +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.raytheon.uf.common.time.DataTime; + +public class GraphTimelineUtil { + /* + * Convert UTC calendar time to next hourSnap point + */ + public static Calendar snapTimeToNext(Calendar refTimeCal, int snap) { + + Calendar dup = (Calendar) refTimeCal.clone(); + if (snap == 0) + return dup; + + int hourOfDay = refTimeCal.get(Calendar.HOUR_OF_DAY); + int hour = refTimeCal.get(Calendar.HOUR); + int min = refTimeCal.get(Calendar.MINUTE); + boolean flag = true; + + if (hourOfDay != hour) + flag = false; + + if (!(hourOfDay % snap == 0 && min == 0)) + hourOfDay = (hourOfDay / snap) * snap + snap; + + dup.set(Calendar.HOUR_OF_DAY, hourOfDay); + if (flag) + dup.set(Calendar.HOUR, hourOfDay); + else + dup.set(Calendar.HOUR, hourOfDay - 12); + + dup.set(Calendar.MINUTE, 0); + + return dup; + } + + /* + * Convert UTC calendar time to next hourSnap point + */ + public static Calendar snapTimeToPrevious(Calendar refTimeCal, int snap) { + + Calendar dup = (Calendar) refTimeCal.clone(); + if (snap == 0) + return dup; + + int hourOfDay = refTimeCal.get(Calendar.HOUR_OF_DAY); + int hour = refTimeCal.get(Calendar.HOUR); + int min = refTimeCal.get(Calendar.MINUTE); + boolean flag = true; + + if (hourOfDay != hour) + flag = false; + + if (!(hourOfDay % snap == 0 && min == 0)) + hourOfDay = (hourOfDay / snap) * snap; + + dup.set(Calendar.HOUR_OF_DAY, hourOfDay); + if (flag) + dup.set(Calendar.HOUR, hourOfDay); + else + dup.set(Calendar.HOUR, hourOfDay - 12); + + dup.set(Calendar.MINUTE, 0); + + return dup; + } + + /* + * Convert UTC calendar time to closest hourSnap point + */ + public static Calendar snapTimeToClosest(Calendar refTimeCal, int snap) { + + Calendar dup = (Calendar) refTimeCal.clone(); + if (snap == 0) + return dup; + + int hourOfDay = refTimeCal.get(Calendar.HOUR_OF_DAY); + int hour = refTimeCal.get(Calendar.HOUR); + int min = refTimeCal.get(Calendar.MINUTE); + boolean flag = true; + + if (hourOfDay != hour) + flag = false; + + if (!(hourOfDay % snap == 0 && min == 0)) { + if (hourOfDay % snap == 0 || (hourOfDay % snap == 1 && min < 30)) + hourOfDay = (hourOfDay / snap) * snap; + else + hourOfDay = (hourOfDay / snap) * snap + snap; + } + + dup.set(Calendar.HOUR_OF_DAY, hourOfDay); + if (flag) + dup.set(Calendar.HOUR, hourOfDay); + else + dup.set(Calendar.HOUR, hourOfDay - 12); + + dup.set(Calendar.MINUTE, 0); + + return dup; + } + + /* + * Move UTC selected calendar time to previous hourSnap point + */ + // public static Calendar slideSelectedTimeToRightBysnap(Calendar + // refTimeCal, + // int snap) { + // + // } + + /** + * sort on datatime + */ + public static void sortAvailableData(List timeList) {// quan + Collections.sort(timeList, new Comparator() { + + @Override + public int compare(DataTime t1, DataTime t2) { + return t1.compareTo(t2); + } + }); + } + + /** + * sort on datatime + */ + public static void sortAvailableCalendar(List timeList) {// quan + Collections.sort(timeList, new Comparator() { + + @Override + public int compare(Calendar t1, Calendar t2) { + return t1.compareTo(t2); + } + }); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java index 0e49244ba9..a950249edd 100644 --- a/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java +++ b/ncep/gov.noaa.nws.ncep.viz.resources/src/gov/noaa/nws/ncep/viz/resources/time_match/NCTimeMatcher.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.TimeZone; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -56,6 +57,7 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties; * 02/12/13 972 Greg Hull changed to work with INatlCntrsDescriptor * 04/24/13 689 Xiaochuan Loop length in slctFrames that is set based on default * or size of selectableDataTimes. + * 05/14/14 1131 Quan Zhou Added graphRange and hourSnap. MouModified generateTimeline * 07/11/14 TTR1032 J. Wu No timeline needed if no data times available. * * @@ -76,6 +78,12 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements @XmlAttribute protected int numFrames; + @XmlAttribute + protected int graphRange; + + @XmlAttribute + protected int hourSnap; + @XmlAttribute protected int skipValue; @@ -94,7 +102,7 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements // all the times in the db based on the dominant resource private List allAvailDataTimes; - // all the times in the db based on the dominant resource + // all the times in the time line based on the dominant resource private List selectableDataTimes; // the frame times that will be used for the RBD @@ -106,6 +114,10 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements private final int dfltNumFrames = 0; + private final int dfltGraphRange = 0; + + private final int dfltHourSnap = 0; + private final int dfltSkipFrames = 0; private boolean timesLoaded = false; @@ -126,6 +138,8 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements selectableDataTimes = new ArrayList(); frameTimes = new ArrayList(); numFrames = dfltNumFrames; + graphRange = dfltGraphRange; + hourSnap = dfltHourSnap; skipValue = dfltSkipFrames; timeRange = 0; // set from dominant resource frameInterval = -1; @@ -144,6 +158,8 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements frameTimes = new ArrayList(tm.frameTimes); timesLoaded = tm.timesLoaded; numFrames = tm.numFrames; + graphRange = tm.graphRange; + hourSnap = tm.hourSnap; skipValue = tm.skipValue; timeRange = tm.timeRange; refTime = (tm.refTime == null ? null : new DataTime( @@ -193,6 +209,22 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements this.numFrames = numFrames; } + public int getHourSnap() { + return hourSnap; + } + + public void setHourSnap(int hourSnap) { + this.hourSnap = hourSnap; + } + + public int getGraphRange() { + return graphRange; + } + + public void setGraphRange(int graphRange) { + this.graphRange = graphRange; + } + public int getSkipValue() { return skipValue; } @@ -223,15 +255,21 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements public void setFrameTimes(ArrayList ft) { frameTimes = ft; + // do we always want to set numFrames here? - numFrames = frameTimes.size(); + if (!this.getDominantResourceName().getRscCategory().getCategoryName() + .equals("TIMESERIES")) + numFrames = frameTimes.size(); + else + numFrames = this.getGraphRange() * 60; } public List getSelectableDataTimes() { return selectableDataTimes; } - public void setSelectableDataTimes(ArrayList selDataTimes) { + + void setSelectableDataTimes(ArrayList selDataTimes) { this.selectableDataTimes = selDataTimes; } @@ -292,6 +330,7 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements frameTimes.clear(); selectableDataTimes.clear(); numFrames = 0; + graphRange = 0; frameInterval = -1; timeRange = 0; isForecast = false; @@ -300,7 +339,8 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements } numFrames = dominantRscData.getDfltNumFrames(); - + graphRange = dominantRscData.getDfltGraphRange(); + hourSnap = dominantRscData.getDfltHourSnap(); timeRange = dominantRscData.getDfltTimeRange(); skipValue = 0; // no default but reset to 0 @@ -337,8 +377,7 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements } // if refTime is null, then either use the most recent data as the refTime - // or the cycle - // time for forecast data. + // or the cycle time for forecast data. public boolean generateTimeline() { frameTimes.clear(); selectableDataTimes.clear(); @@ -356,6 +395,7 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements // refTime is marshalled out to the bundle file and may be null // or 'latest' or a time set by the user. long refTimeMillisecs = 0; + Calendar refTimeCal = null; // if (isForecast) { // check cycleTime instead of isForecast since some resources may @@ -369,12 +409,13 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements } else if (isCurrentRefTime()) { refTimeMillisecs = Calendar.getInstance().getTimeInMillis(); + refTimeCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); } else if (isLatestRefTime()) { refTimeMillisecs = 0; } else { + refTimeCal = refTime.getRefTimeAsCalendar(); refTimeMillisecs = refTime.getRefTime().getTime(); } - /* * Always check all available times. If none of the available data times * falls within the specified time range, then no time line should be @@ -403,13 +444,16 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements // if we need to get the cycle time for a forecast resource, then // we will need to query the times of the dominant resource. if (refTimeMillisecs == 0 || frameInterval == -1) { - // allAvailDataTimes = dominantRscData.getAvailableDataTimes(); + // allAvailDataTimes = dominantRscData.getAvailableDataTimes(); //?? if (allAvailDataTimes == null) { // no data allAvailDataTimes = new ArrayList(); // return false; } + // added sort + GraphTimelineUtil.sortAvailableData(allAvailDataTimes); + // if refTime is not given (ie Latest) then get it from the data if (refTimeMillisecs == 0) { if (!allAvailDataTimes.isEmpty()) { @@ -419,15 +463,24 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements // this // save the sentinel value and get latest when the rbd is // loaded? - // + refTime = allAvailDataTimes.get((isForecast ? 0 : allAvailDataTimes.size() - 1)); + refTimeCal = refTime.getRefTimeAsCalendar(); refTimeMillisecs = refTime.getRefTime().getTime(); } else { return false; } } + // extend refTime to the snap point + if (this.getDominantResourceName().getRscCategory() + .getCategoryName().equals("TIMESERIES") + && this.getHourSnap() != 0) { + refTimeMillisecs = GraphTimelineUtil.snapTimeToNext(refTimeCal, + this.getHourSnap()).getTimeInMillis(); + } + // if generating times from the data then get only those times in // the selected range. if (frameInterval == -1) { @@ -502,6 +555,14 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements } else { int skipCount = 0; // set the initial frameTimes from the skip value and numFrames + GraphTimelineUtil.sortAvailableData(selectableDataTimes); + + /* + * For graph display, numFrames = 1 + */ + if (this.getDominantResourceName().getRscCategory() + .getCategoryName().equals("TIMESERIES")) + numFrames = 1; for (skipCount = 0; skipCount < selectableDataTimes.size(); skipCount++) { if (skipCount % (skipValue + 1) == 0) { @@ -552,6 +613,7 @@ public class NCTimeMatcher extends AbstractTimeMatcher implements if (frameInterval == -1) { if (!frameTimes.contains(newFrameTime)) { newFrameTimes.add(newFrameTime); + //System.out.println("**newFrameTime " + newFrameTime); } } else if (frameInterval != 0) { // if MANUAL or FRAME_TIMES // TODO : we could add forecast updates but right now it doesn't diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.classpath b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.project b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.project new file mode 100644 index 0000000000..2c37589523 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.project @@ -0,0 +1,28 @@ + + + gov.noaa.nws.ncep.viz.rsc.timeseries + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.settings/org.eclipse.jdt.core.prefs b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..f5d125b415 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Feb 13 16:11:02 EST 2012 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..82e28686e4 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/META-INF/MANIFEST.MF @@ -0,0 +1,46 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: timeseries +Bundle-SymbolicName: gov.noaa.nws.ncep.viz.rsc.timeseries;singleton:=true +Eclipse-RegisterBuddy: gov.noaa.nws.ncep.viz.resources, com.raytheon.viz.core, com.raytheon.uf.viz.core, com.raytheon.viz.ui, com.raytheon.edex.common, com.raytheon.uf.common.serialization +Eclipse-BuddyPolicy: ext, global +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: gov.noaa.nws.ncep.viz.rsc.timeseries.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174", + com.raytheon.uf.common.time;bundle-version="1.12.1174", + org.apache.commons.lang;bundle-version="2.3.0", + org.geotools;bundle-version="2.6.4", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + com.raytheon.uf.viz.xy;bundle-version="1.12.1174", + com.raytheon.viz.ui;bundle-version="1.12.1174", + gov.noaa.nws.ncep.common.dataplugin.geomag, + gov.noaa.nws.ncep.viz.localization;bundle-version="1.0.0", + com.raytheon.viz.core.graphing;bundle-version="1.12.1174", + com.raytheon.uf.viz.d2d.ui;bundle-version="1.12.1174", + com.raytheon.uf.viz.d2d.core;bundle-version="1.12.1174", + com.raytheon.uf.common.datastorage;bundle-version="1.12.1174", + com.raytheon.uf.common.colormap;bundle-version="1.12.1174", + com.raytheon.viz.core;bundle-version="1.12.1174", + javax.measure;bundle-version="1.0.0", + gov.noaa.nws.ncep.viz.common, + gov.noaa.nws.ncep.viz.resources;bundle-version="1.0.0", + com.raytheon.uf.common.style;bundle-version="1.0.0", + com.raytheon.uf.viz.xy.timeseries +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: com.raytheon.uf.viz.xy.timeseries.adapter, + com.raytheon.uf.viz.xy.timeseries.display, + com.raytheon.uf.viz.xy.timeseries.graph, + gov.noaa.nws.ncep.common.dataplugin.geomag, + gov.noaa.nws.ncep.common.dataplugin.geomag.calculation, + gov.noaa.nws.ncep.common.dataplugin.geomag.exception, + gov.noaa.nws.ncep.common.dataplugin.geomag.request, + gov.noaa.nws.ncep.common.dataplugin.geomag.table, + gov.noaa.nws.ncep.common.dataplugin.geomag.util, + gov.noaa.nws.ncep.viz.ui.display +Export-Package: gov.noaa.nws.ncep.viz.rsc.timeseries, + gov.noaa.nws.ncep.viz.rsc.timeseries.rsc + diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject new file mode 100644 index 0000000000..4e6c255127 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -0,0 +1 @@ +gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.GeoMagResourceData \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/build.properties b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/build.properties new file mode 100644 index 0000000000..6e2f847b66 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + localization/ diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/gov.noaa.nws.ncep.viz.rsc.timeseries.ecl b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/gov.noaa.nws.ncep.viz.rsc.timeseries.ecl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml new file mode 100644 index 0000000000..8ed9e1d4d9 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/localization/ncep/resourceTemplates/GeoMag.xml @@ -0,0 +1,41 @@ + + + + + + + + + ${frameSpan} + ${dfltNumFrames} + ${dfltTimeRange} + ${timeMatchMethod} + ${timelineGenMethod} + + ${yAxesData} + ${dataColor} + ${xAxesTitle} + ${yAxesTitle} + ${yDescription} + + + + + + + + + + + + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml new file mode 100644 index 0000000000..3a3d579996 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/plugin.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/Activator.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/Activator.java new file mode 100644 index 0000000000..502d7fccd0 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/Activator.java @@ -0,0 +1,72 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer         Description
+ * ------------ ---------- -----------      --------------------------
+ * 02/21/2013   958        qzhou, sgurung   Initial creation
+ * 03/06/2013   958        ghull            rm preferenceStore
+ * 
+ * 
+ * + * @author qzhou, sgurung + * @version 1.0 + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "gov.noaa.nws.ncep.viz.rsc.timeSeries"; //$NON-NLS-1$ + + private IPreferenceStore myprefs = null; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java new file mode 100644 index 0000000000..3e6831f6e3 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagDescriptor.java @@ -0,0 +1,134 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.rsc.timeseries; + +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; +import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; +import gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesDescriptor; +import gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesRenderableDisplay; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.drawables.AbstractDescriptor; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.xy.graph.IGraph; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Geomag descriptor, needed so loading bundles know what editor to load with + * this descriptor. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer   Description
+ * ------------ ---------- ---------- --------------------------
+ * 06/13/2014   #1136      qzhou      Initial creation
+ *                                    Added functions to set it up.
+ * 
+ * + * @author qzhou + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class GeoMagDescriptor extends NCTimeSeriesDescriptor implements + INatlCntrsDescriptor { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(AbstractDescriptor.class); + + public GeoMagDescriptor() { + super(); + } + + public GeoMagDescriptor(PixelExtent pixelExtent) { + super(pixelExtent); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.xy.graph.XyGraphDescriptor#constructGraph() + */ + @Override + public IGraph constructGraph() { + return new GeoMagGraph(this); + } + + public static IDisplayPane[] getDisplayPane() { + // get the pane of the selected resource. + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + + return (IDisplayPane[]) editor.getDisplayPanes(); + + } + + public void addDescriptor(GeoMagDescriptor desc, IDisplayPane pane) { + + NCTimeSeriesRenderableDisplay rendDisp = (NCTimeSeriesRenderableDisplay) pane + .getRenderableDisplay(); + + if (!(rendDisp instanceof NCTimeSeriesRenderableDisplay)) { + try { + throw new VizException( + "Error: can't zoom to resource in the renderable display : " + + rendDisp.getClass().getName()); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + + rendDisp.setDescriptor(desc); + + } + + public void setResourcePair(GeoMagDescriptor desc, IDisplayPane pane) { + + List rlist = pane.getRenderableDisplay().getDescriptor() + .getResourceList(); + + if (rlist != null) { + + ResourcePair[] rp = rlist.toArray(new ResourcePair[rlist.size()]); + desc.setSerializableResources(rp); + } + + } + + public void setNCTimeMatcher(GeoMagDescriptor desc, IDisplayPane pane) { + + NCTimeMatcher tm = (NCTimeMatcher) pane.getDescriptor() + .getTimeMatcher(); + + desc.setTimeMatcher(tm); + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java new file mode 100644 index 0000000000..03960ca2b7 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/GeoMagGraph.java @@ -0,0 +1,704 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.rsc.timeseries; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.table.KStationCoefficient; +import gov.noaa.nws.ncep.common.dataplugin.geomag.util.KStationCoefficientLookup; +import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.GeoMagResource; +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.GeoMagResourceData; +import gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesGraph; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.RGBColors; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource.ResourceStatus; +import com.raytheon.uf.viz.xy.graph.GraphLabelComparator; +import com.raytheon.uf.viz.xy.graph.XyGraphDescriptor; +import com.raytheon.uf.viz.xy.graph.axis.GraphAxis; +import com.raytheon.uf.viz.xy.graph.axis.IAxis; +import com.raytheon.uf.viz.xy.graph.axis.LinearAxisPlacer; +import com.raytheon.uf.viz.xy.graph.labeling.DataTimeLabel; +import com.raytheon.uf.viz.xy.graph.labeling.IGraphLabel; +import com.raytheon.uf.viz.xy.map.rsc.IGraphableResource; +import com.raytheon.viz.core.graphing.xy.XYImageData; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * The geomag graph, needs to be extracted into AbstractGraph + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 06/10/2014   1136       qzhou       Changed graphExtent for time series 1000*400
+ *                                     Added getStationLocalTime. Added paintBorderRect, Added paintMidnightNoon, 
+ *                                     Added paintXTitle. Modified paintTitles. Added ticks on yAxes.
+ * 
+ * + * @author qzhou + * @version 1.0 + */ + +public class GeoMagGraph extends NCTimeSeriesGraph { + + private SimpleDateFormat sdf; + + private int duration; + + private double deltaMax = 0.0; + + public GeoMagGraph(XyGraphDescriptor descriptor) { + super(descriptor); + sdf = new SimpleDateFormat("HHmm"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + } + + @Override + protected void createAxes() { + /* + * graphExtent(25,999,25,875) is not wide enough for time sereis panes. + * Make the wide as 2.5 times of height. Make new extent graphExtent(0, + * 1000, 300, 700). + */ + graphExtent = new PixelExtent(0, 1000, 300, 700); + double minX = graphExtent.getMinX(); + double maxX = graphExtent.getMaxX(); + double minY = graphExtent.getMinY(); + double maxY = graphExtent.getMaxY(); + + // Set up the bounding box axes + minXAxis.setStartLoc(new Coordinate(minX, maxY, 0)); + minXAxis.setEndLoc(new Coordinate(maxX, maxY, 0)); + + maxXAxis.setStartLoc(new Coordinate(minX, minY, 0)); + maxXAxis.setEndLoc(new Coordinate(maxX, minY, 0)); + + minYAxis.setStartLoc(new Coordinate(minX, maxY, 0)); + minYAxis.setEndLoc(new Coordinate(minX, minY, 0)); + + maxYAxis.setStartLoc(new Coordinate(maxX, maxY, 0)); + maxYAxis.setEndLoc(new Coordinate(maxX, minY, 0)); + + // Create the Axis if they do not exist + double halfDelta = getDeltaMax() / 2.0; + xAxes = new IAxis[5]; // fixed 5 + for (int i = 0; i < xAxes.length; ++i) { + xAxes[i] = new GraphAxis(); + xAxes[i].setLineStyle(LineStyle.DOTTED); + xAxes[i].setDrawAxis(true); + + if (i < xAxes.length / 2) + xAxes[i].setDiscreteValue(-halfDelta / (i + 1)); + else if (i > xAxes.length / 2) + xAxes[i].setDiscreteValue(halfDelta / (xAxes.length - i)); + else if (i == xAxes.length / 2) + xAxes[i].setDiscreteValue(00.0); + + } + + xAxisPlacer.setPixelWidth(graphExtent.getHeight()); + yAxisPlacer.setPixelWidth(graphExtent.getWidth()); + + // Place the data axes + double[] offsets = xAxisPlacer.placeAxes(xAxes); + + for (int i = 0; i < offsets.length; ++i) { + double offset = offsets[i]; + xAxes[i].setStartLoc(new Coordinate(minX, maxY - offset, 0)); + xAxes[i].setEndLoc(new Coordinate(maxX, maxY - offset, 0)); + } + + createVerticalAxes(); + } + + private void createVerticalAxes() { + double start = 0; + double end = 0; + if (xLabels.size() > 0) { + start = xLabels.get(0).getDiscreteValue(); + end = xLabels.get(xLabels.size() - 1).getDiscreteValue(); + } + double diff = end - start; + double numint = xLabels.size() - 1; + + yAxes = new IAxis[xLabels.size()]; + for (int i = 0; i < xLabels.size(); ++i) { + yAxes[i] = new GraphAxis(); + yAxes[i].setLineStyle(LineStyle.SOLID); + yAxes[i].setDrawAxis(true); + yAxes[i].setDiscreteValue(start + (diff * i / numint)); + } + + double maxX = graphExtent.getMaxX(); + double maxY = graphExtent.getMaxY(); + + double[] offsets = yAxisPlacer.placeAxes(yAxes); + + for (int i = 0; i < offsets.length; ++i) { + double offset = offsets[i]; + yAxes[i].setStartLoc(new Coordinate(maxX - offset, maxY, 0)); + yAxes[i].setEndLoc(new Coordinate(maxX - offset, maxY, 0)); + } + } + + @Override + protected boolean canHandleResoruce(IGraphableResource rsc) { + // Can only handle graphing of GeoMagResources + return (rsc instanceof GeoMagResource); + } + + @Override + protected void paintUnits(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + + RGB colorToUse = null; + List strings = new ArrayList(); + for (IGraphableResource grsc : graphResource) { + GeoMagResource rsc = (GeoMagResource) grsc; + + if (rsc == null) { + continue; + } else if (rsc.getData() == null) { + continue; + } else if (rsc.getData().getData() == null) { + continue; + } else if (rsc.getData().getData().size() < 1) { + continue; + } + + if (rsc.getProperties().isVisible()) { + + colorToUse = RGBColors.getRGBColor("white"); + + if (rsc.getData() == null + || rsc.getData().getData().size() == 0 + || !(rsc.getData().getData().get(0) instanceof XYImageData)) { + for (int i = 0; i < xAxes.length; i++) { + Coordinate[] coords = xAxes[i].getCoordinates(); + if (coords[0].y < graphExtent.getMinY()) { + continue; + } + + DrawableString parameters = new DrawableString("", + colorToUse); + + parameters.font = unitsFont; + parameters.textStyle = TextStyle.DROP_SHADOW; + parameters.horizontalAlignment = HorizontalAlignment.RIGHT; + parameters.magnification = this.currentMagnification; + + String value = df.format(xAxes[i].getDiscreteValue()); + if (i == 0) { + parameters.verticallAlignment = VerticalAlignment.BOTTOM; + } else { + parameters.verticallAlignment = VerticalAlignment.MIDDLE; + } + parameters.setText(value, colorToUse); + parameters.setCoordinates(coords[0].x, coords[0].y, + coords[0].z); + strings.add(parameters); + } + } + } + } + target.drawStrings(strings); + + paintDataTimeUnits(target, paintProps, xLabels); + } + + @Override + public void constructVirtualExtent() { + + // make sure all resources are initialized + for (IGraphableResource grsc : graphResource) { + GeoMagResource rsc = (GeoMagResource) grsc; + if (rsc.getStatus() != ResourceStatus.INITIALIZED) { + return; + } + } + + // Loop through resources and create extent then call + // updateVirtualExtent + + double[] minMaxY = new double[2]; + xLabels.clear(); + + getXaxisIntervals(xLabels); + double minX = 0; + double maxX = 0; + minMaxY[0] = 0; + minMaxY[1] = 0; + + double delta = getDeltaMax(); + + minMaxY[0] = -1. * delta / 2.0; + minMaxY[1] = delta / 2.0; + + if (xLabels.size() > 0) { + minX = xLabels.get(0).getDiscreteValue(); + maxX = xLabels.get(xLabels.size() - 1).getDiscreteValue(); + } + + // normalizeAxis now takes into accout data that will never be + // negative like wind speed. + // normalizeAxis(minMaxY); + + xAxisPlacer = new LinearAxisPlacer(graphExtent.getHeight(), minMaxY[0], + minMaxY[1]); + yAxisPlacer = new LinearAxisPlacer(graphExtent.getWidth(), minX, // q + maxX); + + updateVirtualExtent(); + + newResources = false; + + } + + private void getXaxisIntervals(List> xLabels) { + for (IGraphableResource grsc : graphResource) { + if (grsc instanceof GeoMagResource) { + GeoMagResource rsc = (GeoMagResource) grsc; + DataTime[] range = rsc.getDataTimes(); + + if (range == null || range.length == 0) + continue; + + DataTime start = range[0]; + xLabels.add(new DataTimeLabel(start)); + DataTime end = range[range.length - 1]; + xLabels.add(new DataTimeLabel(end)); + + NCTimeMatcher tm = (NCTimeMatcher) rsc.getDescriptor() + .getTimeMatcher(); + + if (tm != null) + duration = tm.getGraphRange(); + + int numInterval = 4; + if (duration > 12 & duration < 72) + numInterval = duration / 3; + else if (duration >= 72 & duration < 168) + numInterval = duration / 6; + else if (duration >= 168) + numInterval = duration / 12; + + long diff = end.getRefTime().getTime() + - start.getRefTime().getTime(); + + for (int i = 1; i < numInterval; i++) { + long startTime = start.getRefTime().getTime(); + long newTime = startTime + (diff * i / numInterval); + DataTime dtime = new DataTime(new Date(newTime)); + xLabels.add(new DataTimeLabel(dtime)); + } + } + + for (IGraphLabel label : xLabels) { + label.setResource((AbstractVizResource) grsc); + } + + } + Collections.sort(xLabels, new GraphLabelComparator()); + } + + private double getDeltaFromResource() { + double delta = 0.0; + for (IGraphableResource grsc : graphResource) { + if (grsc instanceof GeoMagResource) { + GeoMagResource rsc = (GeoMagResource) grsc; + + delta = Math.max(delta, rsc.getDelta()); + + } + } + return delta; + } + + private double getDeltaMax() { + + if (deltaMax < getDeltaFromResource()) + deltaMax = getDeltaFromResource(); + return deltaMax; + } + + @Override + protected void paintTitles(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + + RGB colorToUse = RGBColors.getRGBColor("white"); + List baselineAndColor = new ArrayList(); + + // paint first x title + for (IGraphableResource grsc : graphResource) { + GeoMagResource rsc = (GeoMagResource) grsc; + + if (rsc.getProperties().isVisible()) { + if (((GeoMagResourceData) rsc.getResourceData()) + .getYAxesTitle().substring(1, 2).equals(" ")) { + String color = ((GeoMagResourceData) rsc.getResourceData()) + .getDataColor(); + colorToUse = RGBColors.getRGBColor(color); + + paintXTitle(target, paintProps, + ((GeoMagResourceData) rsc.getResourceData()) + .getXAxesTitle(), colorToUse); + } + // break; + } + } + + for (IGraphableResource grsc : graphResource) { + GeoMagResource rsc = (GeoMagResource) grsc; + + if (rsc.getProperties().isVisible() + && ((GeoMagResourceData) rsc.getResourceData()) + .getYAxesTitle().substring(1, 2).equals(" ")) {// H,D + String color = ((GeoMagResourceData) rsc.getResourceData()) + .getDataColor(); + colorToUse = RGBColors.getRGBColor(color); + + NCTimeMatcher tm = (NCTimeMatcher) rsc.getDescriptor() + .getTimeMatcher(); + + String rscTitle = rsc.getTitle(); + + if (!baselineAndColor.contains((rscTitle + "," + color))) { + baselineAndColor.add(rscTitle + "," + color); + + } + } + } + + // consider autoUpdate, only last H or D title will be displayed + List baseline = new ArrayList(); + List baselinePrint = new ArrayList(); + + for (int i = baselineAndColor.size() - 1; i >= 0; i--) { + String[] string = baselineAndColor.get(i).split(","); + String str1 = string[0].substring(0, string[0].indexOf(" ")); + + if (!baseline.contains(str1)) { + baseline.add(str1); + baselinePrint.add(baselineAndColor.get(i)); + } + } + + for (int i = 0; i < baselinePrint.size(); i++) { + String[] string = baselinePrint.get(i).split(","); + if (string.length == 2) + paintYTitle(target, paintProps, string[0], + RGBColors.getRGBColor(string[1]), i + 1); + + } + + paintBorderRect(target, paintProps, xLabels); + + } + + protected void paintXTitle(IGraphicsTarget target, + PaintProperties paintProps, String title, RGB titleColor) + throws VizException { + + DrawableString titleString = new DrawableString(title, titleColor); + titleString.textStyle = TextStyle.DROP_SHADOW; + titleString.horizontalAlignment = HorizontalAlignment.CENTER; + titleString.verticallAlignment = VerticalAlignment.TOP; + titleString.magnification = this.currentMagnification; + + double x = graphExtent.getMinX() + graphExtent.getWidth() / 2; + double y = graphExtent.getMaxY() + 100; + titleString.setCoordinates(x, y); + + target.drawStrings(titleString); + } + + @Override + protected void paintDataTimeUnits(IGraphicsTarget target, + PaintProperties paintProps, List> xLabels) + throws VizException { + + List strings = new ArrayList( + xLabels.size()); + + for (IGraphLabel xLabel : xLabels) { + double val = xLabel.getDiscreteValue(); + Date date = xLabel.getUnderlyingObject().getRefTime(); + + RGB labelColor = RGBColors.getRGBColor("white"); + DrawableString parameters = new DrawableString(sdf.format(date), + labelColor); + + unitsFont = target.initializeFont((String) null, 14.0f, + new IFont.Style[] {}); + parameters.font = unitsFont; + parameters.horizontalAlignment = HorizontalAlignment.CENTER; + parameters.verticallAlignment = VerticalAlignment.TOP; + parameters.magnification = this.currentMagnification; + + double offset = yAxisPlacer.getPixelLoc(val); + + Coordinate loc = new Coordinate(graphExtent.getMinX() + offset, + graphExtent.getMaxY(), 0); + + parameters.setCoordinates(loc.x, loc.y, loc.z); + + strings.add(parameters); + } + target.drawStrings(strings); + + paintMidnightNoon(target, paintProps, xLabels); + + paintTicks(target, paintProps, xLabels); + + } + + private void paintBorderRect(IGraphicsTarget target, + PaintProperties paintProps, List> xLabels) + throws VizException { + + target.drawRect(graphExtent, RGBColors.getRGBColor("white"), 1, 1); + } + + private void paintMidnightNoon(IGraphicsTarget target, + PaintProperties paintProps, List> xLabels) + throws VizException { + + double start = 0; + double end = 0; + if (xLabels.size() > 0) { + start = xLabels.get(0).getDiscreteValue(); + end = xLabels.get(xLabels.size() - 1).getDiscreteValue(); + } + + if (xLabels == null || xLabels.isEmpty()) // q + return; + + String string = xLabels.get(0).getResource().getName(); + // Example: string = BOU - H_Component - Begin: 0000 UTC 06 May 2013 + double localTime = getStationLocalTime(string.substring(0, 3)); + + for (int i = 0; i < xLabels.size(); i++) { + int hour = xLabels.get(i).getUnderlyingObject().getValidTime() + .get(Calendar.HOUR_OF_DAY); + + // print midnight= orange. noon=yellow + if (hour == 0) { + double val = xLabels.get(i).getDiscreteValue() + localTime + * 3600 * 1000; + + if (val >= start && val <= end) { + double offset = yAxisPlacer.getPixelLoc(val); + + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMinY(), 0, graphExtent.getMinX() + + offset, graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("orange"), 1, + LineStyle.DASHED); + target.drawString(unitsFont, "M", graphExtent.getMinX() + + offset, graphExtent.getMinY(), 0.0, + TextStyle.DROP_SHADOW, + RGBColors.getRGBColor("orange"), + HorizontalAlignment.CENTER, + VerticalAlignment.BOTTOM, 0.0); + } else if (val < start) { + val = val + 12;// noon + double offset = yAxisPlacer.getPixelLoc(val); + + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMinY(), 0, graphExtent.getMinX() + + offset, graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("yellow"), 1, + LineStyle.DASHED); + target.drawString(unitsFont, "N", graphExtent.getMinX() + + offset, graphExtent.getMinY(), 0.0, + TextStyle.DROP_SHADOW, + RGBColors.getRGBColor("yellow"), + HorizontalAlignment.CENTER, + VerticalAlignment.BOTTOM, 0.0); + // } else if (val > end) { // sometimes get an extra line + // val = val - 12;// noon + // double offset = yAxisPlacer.getPixelLoc(val); + // + // target.drawLine(graphExtent.getMinX() + offset, + // graphExtent.getMinY(), 0, graphExtent.getMinX() + // + offset, graphExtent.getMaxY(), 0, + // RGBColors.getRGBColor("yellow"), 1, + // LineStyle.DASHED); + } + + } else if (hour == 12) { + double val = xLabels.get(i).getDiscreteValue() + localTime + * 3600 * 1000; + + if (val > start && val < end) { + double offset = yAxisPlacer.getPixelLoc(val); + + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMinY(), 0, graphExtent.getMinX() + + offset, graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("yellow"), 1, + LineStyle.DASHED); + target.drawString(unitsFont, "N", graphExtent.getMinX() + + offset, graphExtent.getMinY(), 0.0, + TextStyle.DROP_SHADOW, + RGBColors.getRGBColor("yellow"), + HorizontalAlignment.CENTER, + VerticalAlignment.BOTTOM, 0.0); + } else if (val < start) { + val = val + 12;// noon + double offset = yAxisPlacer.getPixelLoc(val); + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMinY(), 0, graphExtent.getMinX() + + offset, graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("orange"), 1, + LineStyle.DASHED); + target.drawString(unitsFont, "M", graphExtent.getMinX() + + offset, graphExtent.getMinY(), 0.0, + TextStyle.DROP_SHADOW, + RGBColors.getRGBColor("orange"), + HorizontalAlignment.CENTER, + VerticalAlignment.BOTTOM, 0.0); + // } else if (val > end) { + // val = val - 12;// noon + // double offset = yAxisPlacer.getPixelLoc(val); + // target.drawLine(graphExtent.getMinX() + offset, + // graphExtent.getMinY(), 0, graphExtent.getMinX() + // + offset, graphExtent.getMaxY(), 0, + // RGBColors.getRGBColor("orange"), 1, + // LineStyle.DASHED); + } + } + } + } + + /* + * get station local time based on longitude. return the local time when utc + * time hour is 0. + */ + private double getStationLocalTime(String stnCode) { + double local = 0; + + KStationCoefficientLookup lookup = KStationCoefficientLookup + .getInstance(); + KStationCoefficient coefficient = lookup.getStationByCode(stnCode); + String longitude = coefficient.getLongitude(); + + double lon = Float.parseFloat(longitude); + + local = 24 - (lon / 15); + + return local; + } + + private void paintTicks(IGraphicsTarget target, PaintProperties paintProps, + List> xLabels) throws VizException { + + // X Axes ticks + if (duration <= 24) { + int count = 0; + double temp = 0; + for (int i = 0; i < xLabels.size(); i++) { + if (temp != xLabels.get(i).getDiscreteValue()) { + temp = xLabels.get(i).getDiscreteValue(); + count++; + } + } + + int size = (count - 1) * 3 + 1; + + double start = 0; + double end = 0; + if (xLabels.size() > 0) { + start = xLabels.get(0).getDiscreteValue(); + end = xLabels.get(xLabels.size() - 1).getDiscreteValue(); + } + double diff = end - start; + + for (int i = 0; i < size; ++i) { + + double val = start + (diff * i / (size - 1)); + double offset = yAxisPlacer.getPixelLoc(val); + + if (i % 3 == 0) + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMaxY() - 15, 0, + graphExtent.getMinX() + offset, + graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("white"), 1, LineStyle.SOLID); + else + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMaxY() - 10, 0, + graphExtent.getMinX() + offset, + graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("white"), 1, LineStyle.SOLID); + + } + } else { + + for (int i = 0; i < xLabels.size(); ++i) { + + double val = xLabels.get(i).getDiscreteValue(); + double offset = yAxisPlacer.getPixelLoc(val); + + target.drawLine(graphExtent.getMinX() + offset, + graphExtent.getMaxY() - 15, 0, graphExtent.getMinX() + + offset, graphExtent.getMaxY(), 0, + RGBColors.getRGBColor("white"), 1, LineStyle.SOLID); + + } + } + + // Y Axes ticks, fixed 9 + for (int i = 0; i < 9; ++i) { + + double offset = (graphExtent.getMaxY() - graphExtent.getMinY()) + / (9 - 1); + + target.drawLine(graphExtent.getMinX(), graphExtent.getMinY() + + offset * i, 0, graphExtent.getMinX() + 10, + graphExtent.getMinY() + offset * i, 0, + RGBColors.getRGBColor("white"), 1, LineStyle.SOLID); + + } + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/actions/EnableKTableViewAction.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/actions/EnableKTableViewAction.java new file mode 100644 index 0000000000..6a24fa8a4c --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/actions/EnableKTableViewAction.java @@ -0,0 +1,70 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.actions; + +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.GeoMagResource; + +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * + * Enable/Disable KTableView for GeoMagResource + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ * 07/07/2014    R4079       qzhou     Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ + +public class EnableKTableViewAction extends AbstractRightClickAction { + boolean isEnabled; + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + AbstractVizResource rsc = getSelectedRsc(); + if (rsc instanceof GeoMagResource) { + ((GeoMagResource) rsc).reopenKTableView(); + + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.cmenu.AbstractRightClickAction#setSelectedRsc(com + * .raytheon.uf.viz.core.rsc.AbstractVizResource) + */ + @Override + public void setSelectedRsc(ResourcePair selectedRsc) { + super.setSelectedRsc(selectedRsc); + AbstractVizResource rsc = getSelectedRsc(); + if (rsc instanceof GeoMagResource) { + + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return "Open KTableView"; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/actions/EnableSamplingAction.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/actions/EnableSamplingAction.java new file mode 100644 index 0000000000..744960a257 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/actions/EnableSamplingAction.java @@ -0,0 +1,69 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.actions; + +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.GeoMagResource; + +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * + * Enable/Disable Sampling for GeoMagResource + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ * 07/07/2014    R4079       qzhou     Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ + +public class EnableSamplingAction extends AbstractRightClickAction { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + AbstractVizResource rsc = getSelectedRsc(); + if (rsc instanceof GeoMagResource) { + ((GeoMagResource) rsc).reopenSamplingView(); + + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.cmenu.AbstractRightClickAction#setSelectedRsc(com + * .raytheon.uf.viz.core.rsc.AbstractVizResource) + */ + @Override + public void setSelectedRsc(ResourcePair selectedRsc) { + super.setSelectedRsc(selectedRsc); + AbstractVizResource rsc = getSelectedRsc(); + if (rsc instanceof GeoMagResource) { + + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getText() + */ + @Override + public String getText() { + return "Open Readout"; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java new file mode 100644 index 0000000000..ce5dd2e914 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/EditTimeSeriesAttrsDialog.java @@ -0,0 +1,84 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.rsc; + +import gov.noaa.nws.ncep.viz.resources.INatlCntrsResourceData; +import gov.noaa.nws.ncep.viz.resources.attributes.AbstractEditResourceAttrsInteractiveDialog; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Shell; + +/** + * An interface to edit TimeSeries resource attributes. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 06/18/2014   #1136       qzhou        Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ + +public class EditTimeSeriesAttrsDialog extends + AbstractEditResourceAttrsInteractiveDialog { + + public EditTimeSeriesAttrsDialog(Shell parentShell, + INatlCntrsResourceData r, Boolean apply) { + + super(parentShell, r, apply); + resourceData = r; + + } + + private INatlCntrsResourceData resourceData; + + @Override + public Composite createDialog(Composite topComp) { + + FormLayout layout0 = new FormLayout(); + topComp.setLayout(layout0); + + Composite top = topComp; + + GridLayout mainLayout = new GridLayout(1, true); + mainLayout.marginHeight = 1; + mainLayout.marginWidth = 1; + top.setLayout(mainLayout); + + Group colorsGroup = new Group(top, SWT.SHADOW_NONE); + colorsGroup.setText("Colors"); + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.horizontalAlignment = SWT.FILL; + colorsGroup.setLayoutData(gd); + + initializeComponents(colorsGroup); + + return topComp; + } + + public void initializeComponents(final Group colorsGroup) { + + colorsGroup.setLayout(new GridLayout(2, true)); + + } + + @Override + public void initWidgets() { + // done in createDialog + } + + @Override + protected void dispose() { + super.dispose(); + + } +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java new file mode 100644 index 0000000000..12267bb83a --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResource.java @@ -0,0 +1,1231 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.rsc.timeseries.rsc; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagAvg; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; +import gov.noaa.nws.ncep.common.dataplugin.geomag.calculation.CalcEach3hr; +import gov.noaa.nws.ncep.common.dataplugin.geomag.calculation.CalcUtil; +import gov.noaa.nws.ncep.common.dataplugin.geomag.exception.GeoMagException; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.DatabaseUtil; +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource; +import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource; +import gov.noaa.nws.ncep.viz.resources.time_match.GraphTimelineUtil; +import gov.noaa.nws.ncep.viz.resources.time_match.NCTimeMatcher; +import gov.noaa.nws.ncep.viz.rsc.timeseries.GeoMagDescriptor; +import gov.noaa.nws.ncep.viz.rsc.timeseries.GeoMagGraph; +import gov.noaa.nws.ncep.viz.rsc.timeseries.view.KTableView; +import gov.noaa.nws.ncep.viz.rsc.timeseries.view.SamplingView; +import gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesDescriptor; +import gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesRenderableDisplay; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; +import gov.noaa.nws.ncep.viz.ui.display.NcPaneID; + +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; + +import javax.measure.converter.AddConverter; +import javax.measure.converter.UnitConverter; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.PixelCoverage; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.RGBColors; +import com.raytheon.uf.viz.core.catalog.LayerProperty; +import com.raytheon.uf.viz.core.catalog.ScriptCreator; +import com.raytheon.uf.viz.core.comm.Connector; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IInputHandler; +import com.raytheon.uf.viz.core.rsc.IInputHandler.InputPriority; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.ResourceType; +import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; +import com.raytheon.uf.viz.xy.graph.IGraph; +import com.raytheon.uf.viz.xy.graph.XyGraphDescriptor; +import com.raytheon.uf.viz.xy.graph.labeling.DataTimeLabel; +import com.raytheon.uf.viz.xy.graph.labeling.DoubleLabel; +import com.raytheon.uf.viz.xy.graph.labeling.IGraphLabel; +import com.raytheon.uf.viz.xy.map.rsc.IGraphableResource; +import com.raytheon.uf.viz.xy.timeseries.rsc.TimeSeriesResource; +import com.raytheon.viz.core.graphing.xy.XYData; +import com.raytheon.viz.core.graphing.xy.XYDataList; +import com.raytheon.viz.core.graphing.xy.XYImageData; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * The resource class for GeoMagResource. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 02/27/2014              qzhou       Initial
+ * 06/04/2014   #1136      qzhou       Added graph paintInternal. Added GeoMagDescriptor
+ * 06/24/2014   #1136      qzhou       Modified loadInternal. Modified getTitle
+ * 06/25/2014   #1136      qzhou       Fixed graph painting duplicated errors. Qdc subtract component's median.
+ * 07/03/2014   R4079      qzhou       Added k-index view.
+ * 07/10/2014   R4079      qzhou       Added SamplingView and Sampling related classes.
+ * 
+ * + * @author qzhou + * @version 1.0 + */ +public class GeoMagResource extends + AbstractNatlCntrsResource + implements IGraphableResource, INatlCntrsResource, + IResourceDataChanged { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(GeoMagResource.class); + + /* + * sampling related + */ + // boolean sampling = true; + + private final IInputHandler inputAdapter = getGeoMagSamplingInputHandler(); + + private final Sampling samplingRsc; + + protected ReferencedCoordinate sampleCoord; + + private final SimpleDateFormat timeSampleFormat = new SimpleDateFormat( + "yyyy/MM/dd'T'HH':'mm"); + + protected static class SampleResult { + + public SampleResult() { + } + + public String[] labels; + + public RGB[] colors; + } + + /* + * TimeSeries related + */ + private GeoMagResourceData geoMagData; + + protected IDisplayPane currentPane; + + private final SimpleDateFormat dateFmt = new SimpleDateFormat( + "yyyyMMdd/HHmm"); + + /** The data in xy form */ + protected volatile XYDataList data = new XYDataList(); + + protected String units; + + /** Denotes whether shapes are plotted at each data point * */ + protected boolean shapesVisible = false;// + + /** The graph to draw to */ + protected IGraph graph = null; + + private Set dataTimes = new TreeSet(); + + protected NCTimeMatcher timeMatcher; + + protected DataTime timelineStart; + + protected DataTime timelineEnd; + + /* + * geomag related + */ + protected List magRecords; + + private UnitConverter toDeltanT; + + protected float[] hQdc; + + protected float[] dQdc; + + private float yMedian; + + /* + * class FrameData not used except legenda + */ + protected class FrameData extends AbstractFrameData { + + // save only the image which best time matches to this frame. + // if this is the dominant resource then this will be an exact match + // since this record's time was used to generate the timeline. + + private GeoMagGraph geoMagGraph; + + private long timeMatch = -1; + + private String legendStr = "No Data"; + + protected FrameData(DataTime time, int interval) { + super(time, interval); + dateFmt.setTimeZone(TimeZone.getTimeZone("GMT")); + + } + + // use the dfltRecordRscDataObj which just stores the one + @Override + public boolean updateFrameData(IRscDataObject rscDataObj) { + PluginDataObject pdo = ((DfltRecordRscDataObj) rscDataObj).getPDO(); + + GeoMagRecord gmRec = (GeoMagRecord) pdo; + + long newTimeMatch = timeMatch(pdo.getDataTime()); + long currTime = 0; + if (newTimeMatch < 0) { // sanity check. + return false; + } + + if (geoMagGraph == null) { + try { + + currTime = pdo.getDataTime().getValidTime().getTime() + .getTime(); + geoMagGraph = new GeoMagGraph( + (XyGraphDescriptor) descriptor); + setLegendForFrame(gmRec); + + } catch (Exception e) { + statusHandler.handle( + Priority.PROBLEM, + "Error creating NCTimeSeriesDisplay" + + e.getLocalizedMessage(), e); + + return false; + } + timeMatch = newTimeMatch; + if (geoMagGraph != null) { + return true; + } + } + + // determine if this image is a better time match than current one + if (newTimeMatch < timeMatch) { + currTime = pdo.getDataTime().getValidTime().getTime().getTime(); + geoMagGraph = new GeoMagGraph((XyGraphDescriptor) descriptor); + setLegendForFrame(gmRec); + + timeMatch = newTimeMatch; + return true; + } + + return false; + } + + public String getLegendForFrame() { + return legendStr; + } + + public void setLegendForFrame(GeoMagRecord rec) { + + String timeStr = dateFmt.format(rec.getDataTime().getRefTime()); + + // from nameGenerator + String stationCode = rec.getStationCode(); + + String source = ""; + int sourceId = rec.getSourceId(); + if (sourceId == 101) { + source = "direct"; + } + + legendStr = stationCode + " " + source + " " + timeStr; + + } + + @Override + public void dispose() { + + super.dispose(); + } + } + + protected GeoMagResource(GeoMagResourceData resData, + LoadProperties loadProperties) { + + super(resData, loadProperties); + geoMagData = resData; + reopenKTableView(); + reopenSamplingView(); + + samplingRsc = new Sampling(); + } + + @Override + protected void disposeInternal() { + + if (data != null) { + data.dispose(); + } + this.data = null; + + IDisplayPaneContainer container = getResourceContainer(); + if (container != null) { + container.unregisterMouseHandler(inputAdapter); + } + + if (samplingRsc != null) { + samplingRsc.dispose(); + } + + if (currentPane != null) + currentPane.dispose(); + + super.disposeInternal(); + } + + @Override + public void paintFrame(AbstractFrameData frmData, IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + + } + + @Override + public void initResource(IGraphicsTarget target) throws VizException { + getDescriptor().getResourceList().instantiateResources(getDescriptor(), + true); + if (descriptor.getRenderableDisplay().getContainer().getDisplayPanes().length > 1) { + ((NCTimeSeriesDescriptor) descriptor).getTimeMatcher() + .redoTimeMatching(((NCTimeSeriesDescriptor) descriptor)); + + } + + NCTimeMatcher tm = (NCTimeMatcher) ((NCTimeSeriesDescriptor) descriptor) + .getTimeMatcher(); + + IDisplayPaneContainer container = getResourceContainer(); + if (container != null) { + container + .registerMouseHandler(inputAdapter, InputPriority.RESOURCE); + } + + DataTime[] timelineStartEnd = getQueryTime(timelineStart, timelineEnd); + timelineStart = timelineStartEnd[0]; + timelineEnd = timelineStartEnd[1]; + geoMagData.setStartTime(timelineStart); + queryRecords(); + } + + public DataTime[] getQueryTime(DataTime timelineStart, DataTime timelineEnd) { + DataTime[] dataTimes = new DataTime[2]; + Long stl = Long.MAX_VALUE; + Long etl = Long.MIN_VALUE; + + for (AbstractFrameData afd : frameDataMap.values()) { + if (stl > afd.getFrameStartTime().getRefTime().getTime()) { + + stl = afd.getFrameStartTime().getRefTime().getTime(); + } + if (etl < afd.getFrameEndTime().getRefTime().getTime()) { + + etl = afd.getFrameEndTime().getRefTime().getTime(); + } + + } + Date start = new Date(stl); + start.setSeconds(0); + Date end = new Date(etl); + end.setSeconds(0); + + timelineStart = new DataTime(start); + timelineEnd = new DataTime(end); + + // snap to synoptic point + timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + if (timelineStart.getRefTime().getMinutes() != 0) { + + Calendar tem = GraphTimelineUtil.snapTimeToClosest( + timelineStart.getRefTimeAsCalendar(), + timeMatcher.getHourSnap()); + timelineStart = new DataTime(tem); + + tem = GraphTimelineUtil.snapTimeToClosest( + timelineEnd.getRefTimeAsCalendar(), + timeMatcher.getHourSnap()); + timelineEnd = new DataTime(tem); + } + + dataTimes[0] = timelineStart; + dataTimes[1] = timelineEnd; + + return dataTimes; + } + + // override base version to constrain on the selected timeline + @Override + public void queryRecords() throws VizException { + + HashMap queryList = new HashMap( + resourceData.getMetadataMap()); + RequestConstraint reqConstr = new RequestConstraint(); + + String startTimeStr = timelineStart.toString().substring(0, 19); + String endTimeStr = timelineEnd.toString().substring(0, 19); + + String[] constraintList = { startTimeStr, endTimeStr }; + reqConstr.setBetweenValueList(constraintList); + reqConstr.setConstraintType(RequestConstraint.ConstraintType.BETWEEN); + + queryList.put("dataTime.refTime", reqConstr); + + LayerProperty prop = new LayerProperty(); + prop.setDesiredProduct(ResourceType.PLAN_VIEW); + prop.setEntryQueryParameters(queryList, false); + prop.setNumberOfImages(100000); + + String script = null; + script = ScriptCreator.createScript(prop); + + if (script == null) + return; + + magRecords = new ArrayList(); + Object[] pdoList = Connector.getInstance().connect(script, null, 60000); + + for (Object pdo : pdoList) { + for (IRscDataObject dataObject : processRecord(pdo)) { + newRscDataObjsQueue.add(dataObject); + magRecords + .add((GeoMagRecord) ((DfltRecordRscDataObj) dataObject) + .getPDO()); + } + } + + sortRecord(); + data = loadInternal(magRecords); + + // get median before filling null to data + String geoMagType = ((GeoMagResourceData) resourceData).getYAxesData(); + float[] temp = RetrieveUtils.getMedian(magRecords); + + if (geoMagType.startsWith("H")) { + yMedian = temp[0]; + + } else { + yMedian = temp[1]; + } + + // Often magRecord is not end at a synoptic point. So append null to + // magRecords if it does not end at a synoptic point. + + int recSize = data.getData().size(); + if (recSize > 0) { + DataTime last = (DataTime) data.getData().get(recSize - 1).getX(); + Calendar lastCal = last.getRefTimeAsCalendar(); + Calendar cal = (Calendar) lastCal.clone(); + cal = GraphTimelineUtil.snapTimeToNext(cal, + timeMatcher.getHourSnap()); + int fill = (int) (cal.getTimeInMillis() - lastCal.getTimeInMillis()) / 60000; + + for (int i = 0; i < fill; i++) { + lastCal.add(Calendar.MINUTE, 1); + Calendar appendCal = (Calendar) lastCal.clone(); + + XYData d = new XYData(new DataTime(appendCal), null); + data.getData().add(d); + } + + dataTimes = new TreeSet(); + for (XYData d : data.getData()) { + dataTimes.add((DataTime) d.getX()); + } + } + + } + + private XYDataList loadInternal(List recordsList) { + + ArrayList data = new ArrayList(); + if (recordsList.size() <= 1) + return new XYDataList(); + + int recordSize = recordsList.size(); + String geoMagType = ((GeoMagResourceData) resourceData).getYAxesData(); + + Calendar endTime = recordsList.get(recordSize - 1).getDataTime() + .getValidTime(); + + Date spTime = CalcUtil.getSPTime(RetrieveUtils.getUtcDate(endTime)); + Date start = new Date(spTime.getTime() - 30l * 24l * 3600l * 1000l); + + // get qdc from database + List avgList = null; + + try { + avgList = RetrieveUtils.retrieveHrAvgs(recordsList.get(0) + .getStationCode(), start, spTime); + + } catch (GeoMagException e) { + System.out + .println("GeoMagResource: Error retrieving average record."); + } + + if (avgList != null && avgList.size() >= 5) { + List dateListFinal = new ArrayList(); + List hHrAvgListFinal = new ArrayList(); + List dHrAvgListFinal = new ArrayList(); + + DatabaseUtil.fillHrAvgTimeGaps(avgList, dateListFinal, + hHrAvgListFinal, dHrAvgListFinal, spTime); + + float[] hHrAvgs = CalcUtil.toFloatArray(hHrAvgListFinal); + float[] dHrAvgs = CalcUtil.toFloatArray(dHrAvgListFinal); + + hQdc = CalcEach3hr.getHQdcOrDQdc(hHrAvgs, dHrAvgs); + dQdc = CalcEach3hr.getHQdcOrDQdc(dHrAvgs, hHrAvgs); + // qdcSize = 1440 + } + + NCTimeMatcher tm = (NCTimeMatcher) ((NCTimeSeriesDescriptor) descriptor) + .getTimeMatcher(); + int graphSize = tm.getGraphRange() * 60; + + /* + * If load 12 hour record, calculate Qdc. To get Qdc, get 30 days + * hourAvgs before the spTime. + */ + if (recordSize <= 721 + && ((geoMagType.equals("HQdc") || geoMagType.equals("DQdc")))) { + + int i = 0; + Float y = 0f; + for (i = 0; i < recordSize; i++) { + + DataTime x = recordsList.get(i).getDataTime(); + + if (geoMagType.equals("HQdc")) { + if (i == graphSize) + y = hQdc[1440 - 1]; + else + y = hQdc[1440 - graphSize + i]; + + } else if (geoMagType.equals("DQdc")) { + if (i == graphSize) + y = dQdc[1440 - 1]; + else + y = dQdc[1440 - graphSize + i]; + } + + data.add(new XYData(x, y)); + + } + + // if !(hour % 3 == 2 && minute == 59), add Qdc to end of synoptic + // time. Not for others + DataTime extent = recordsList.get(i - 1).getDataTime(); + + int hour = ((Calendar) extent.getValidTime()) + .get(Calendar.HOUR_OF_DAY); + int minute = ((Calendar) extent.getValidTime()) + .get(Calendar.MINUTE); + + if (!(hour % 3 == 2 && minute == 59)) { + + int fillSize = 3 * 60 - (hour * 60 + minute); + Calendar cal = extent.getValidTime(); + + for (int j = 0; j < fillSize; j++) { + cal.add(Calendar.MINUTE, 1); + Calendar time = (Calendar) cal.clone(); + DataTime x = new DataTime(time); + + if (geoMagType.equals("HQdc")) { + y = hQdc[1440 - fillSize + j]; + + } else if (geoMagType.equals("DQdc")) { + y = dQdc[1440 - fillSize + j]; + } + + data.add(new XYData(x, y)); + } + } + } + + else { + for (GeoMagRecord record : recordsList) { + DataTime x = record.getDataTime(); + Float y = 0f; + if (geoMagType.equalsIgnoreCase("H")) + y = record.getComponent_1(); + else if (geoMagType.equalsIgnoreCase("D")) + y = record.getComponent_2(); + + data.add(new XYData(x, y)); + } + + } + XYDataList list = new XYDataList(); + list.setData(data); + + return list; + } + + public void autoupdateRecords() { + + } + + public void reopenKTableView() { + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(KTableView.kTableId); + if (!wpage.isPartVisible(vpart)) { + KTableView paletteWin = KTableView.getAccess(); + if (paletteWin != null) + paletteWin.setEditorVisible(true); + + try { + vpart = wpage.showView(KTableView.kTableId); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void reopenSamplingView() { + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(SamplingView.samplingId); + if (!wpage.isPartVisible(vpart)) { + SamplingView paletteWin = SamplingView.getAccess(); + if (paletteWin != null) + paletteWin.setEditorVisible(true); + + try { + vpart = wpage.showView(SamplingView.samplingId); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.sampling.ISamplingResource#isSampling() + */ + + public IInputHandler getGeoMagSamplingInputHandler() { + return new SamplingInputAdapter(this); + } + + @Override + protected AbstractFrameData createNewFrame(DataTime frameTime, + int frameInterval) { + return new FrameData(frameTime, frameInterval); + } + + @Override + public void propertiesChanged(ResourceProperties updatedProps) { + + } + + // public static synchronized JAXBManager getJaxbManager() + // throws JAXBException { + // if (jaxb == null) { + // SubClassLocator locator = new SubClassLocator(); + // Collection> classes = JAXBClassLocator.getJAXBClasses( + // locator, StyleRuleset.class, StyleRule.class, Level.class, + // AbstractStylePreferences.class, MatchCriteria.class); + // + // locator.save(); + // + // Class[] jaxbClasses = new Class[classes.size() + 1]; + // classes.toArray(jaxbClasses); + // + // /* + // * Add JaxbDummyObject at the beginning so properties are loaded + // * correctly + // */ + // jaxbClasses[jaxbClasses.length - 1] = jaxbClasses[0]; + // jaxbClasses[0] = JaxbDummyObject.class; + // + // jaxb = new JAXBManager(jaxbClasses); + // } + // return jaxb; + // } + + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.DATA_UPDATE) { + PluginDataObject[] objects = (PluginDataObject[]) object; + // for (PluginDataObject pdo : objects) { + // addRecord(pdo); + // } + } + issueRefresh(); + } + + private void sortRecord() { + Collections.sort(magRecords, new Comparator() { + + @Override + public int compare(GeoMagRecord g1, GeoMagRecord g2) { + DataTime t1 = (DataTime) g1.getDataTime(); + DataTime t2 = (DataTime) g2.getDataTime(); + return t1.compareTo(t2); + } + }); + } + + public String getLegendStr() { + FrameData curFrame = (FrameData) getCurrentFrame(); + return (curFrame != null ? curFrame.getLegendForFrame() + : "No Matching Data"); + } + + public String getUnits() { + return units; + } + + /** + * @return the data + */ + public XYDataList getData() { + return data; + } + + /** + * @param data + * the data to set + */ + public void setData(XYDataList data) { + this.data = data; + } + + @Override + public Object getGraphKey() { + return (units != null ? units : "D");// adapter.getParameterName()); + } + + public double getDelta() { + double delta = getMaxDataValue() - getMinDataValue(); + + if (delta <= 20) + return 40; + else if (delta <= 60) + return 80; + else if (delta <= 100) + return 120; + else if (delta <= 140) + return 160; + else if (delta <= 200) + return 200; + else if (delta <= 400) + return 400; + else if (delta <= 800) + return 800; + else if (delta <= 1600) + return 1600; + else + return 3200; + } + + /* + * don't use paintFrame since we don't want to updateFrame many times + * + * @see + * gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource#paintInternal + * (com.raytheon.uf.viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + public void paintInternal(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + + Double magnification = getCapability(MagnificationCapability.class) + .getMagnification(); + + if (data == null) { + return; + } + + /* + * if autoupdate, reconstruct graph extent. Only display the graph when + * the synoptic time changes. + */ + + if (graph != null && timelineStart != geoMagData.getStartTime()) { + + graph.reconstruct(); + geoMagData.setStartTime(timelineStart); + + } + + boolean changeExtent = false; + timeMatcher = (NCTimeMatcher) descriptor.getTimeMatcher(); + + if (timeMatcher.isAutoUpdateable()) { + + while (!newRscDataObjsQueue.isEmpty()) { + IRscDataObject rscDataObj = newRscDataObjsQueue.poll(); + + if (rscDataObj.getDataTime().compareTo(timelineEnd) > 0) { + changeExtent = true; + timelineStart = RetrieveUtils.moveToNextSynop( + timelineStart, timeMatcher.getHourSnap()); + + timelineEnd = RetrieveUtils.moveToNextSynop(timelineEnd, + timeMatcher.getHourSnap()); + + break; + } + } + + if (changeExtent) { + ArrayList newList = new ArrayList(); + for (int i = 0; i < newRscDataObjsQueue.size(); i++) { + DataTime dataTime = newRscDataObjsQueue.poll() + .getDataTime(); + + if (dataTime.compareTo(timelineStart) >= 0 + && dataTime.compareTo(timelineEnd) <= 0) { + + newList.add(dataTime); + } + } + timeMatcher.updateTimeline(newList); + + } + + newRscDataObjsQueue.clear(); + queryRecords(); + + } + + /* + * get gmDescriptor and graph + */ + IDisplayPane[] pane = GeoMagDescriptor.getDisplayPane(); + for (int i = 0; i < pane.length; i++) { + + if (checkPaneId((NCTimeSeriesDescriptor) descriptor, pane[i])) { + GeoMagDescriptor gmDescriptor = new GeoMagDescriptor(); + gmDescriptor.setResourcePair(gmDescriptor, pane[i]); + gmDescriptor.setNCTimeMatcher(gmDescriptor, pane[i]); + gmDescriptor.addDescriptor(gmDescriptor, pane[i]); + gmDescriptor.setAutoUpdate(true);// + graph = gmDescriptor.getGraph(this); + currentPane = pane[i]; + break; + } + } + + /* + * Wait for graph to initialize before plotting to it, TODO: better + */ + if (graph.isReady() == false) { + return; + } + + if (toDeltanT == null) { + toDeltanT = createDataConverter(); + } + + graph.setCurrentMagnification(magnification); + IExtent extent = ((GeoMagGraph) graph).getExtent(); + target.setupClippingPlane(extent); + + /* + * display data + */ + double[] prevScreen = null; + String dataColor = ((GeoMagResourceData) resourceData).getDataColor(); + + RGB color = RGBColors.getRGBColor(dataColor); + + for (int i = 0; i < data.getData().size(); i++) { + + XYData point = data.getData().get(i); + + if (point.getY() != null) { + double newY = toDeltanT.convert(((Number) point.getY()) + .doubleValue()); + + double[] screen = getScreenPosition(point.getX(), newY); + + // Draws shapes for each data point + // draw wind Data + if (point instanceof XYImageData) { + // Draw all images in a striaight line. Move the line to be + // able to accomodate multiple resources. + List> tsrs = descriptor + .getResourceList().getResourcesByType( + TimeSeriesResource.class); + int index = tsrs.indexOf(this); + // IExtent extent = graph.getExtent(); + screen[1] = extent.getMinY() + (index + 1) + * (extent.getHeight() / (tsrs.size() + 1)); + XYImageData imageData = (XYImageData) point; + imageData.setColor(color); + imageData.setTarget(target); + PaintProperties imagePaintProperties = new PaintProperties( + paintProps); + imagePaintProperties.setAlpha(1.0f); + double ratio = paintProps.getView().getExtent().getWidth() + / paintProps.getCanvasBounds().width; + + int[] dims = imageData.getDefaultSize(); + double adjDims[] = new double[2]; + adjDims[0] = (dims[0] * 0.5 * ratio) * magnification; + adjDims[1] = (dims[1] * 0.5 * ratio) * magnification; + + Coordinate ul = new Coordinate(screen[0] - adjDims[0], + screen[1] - adjDims[1]); + Coordinate ur = new Coordinate(screen[0] + adjDims[0], + screen[1] - adjDims[1]); + Coordinate lr = new Coordinate(screen[0] + adjDims[0], + screen[1] + adjDims[1]); + Coordinate ll = new Coordinate(screen[0] - adjDims[0], + screen[1] + adjDims[1]); + PixelCoverage coverage = new PixelCoverage(ul, ur, lr, ll); + + target.drawRaster(imageData.getImage(), coverage, + imagePaintProperties); + continue; + } + + if (shapesVisible) { + target.drawRect(new PixelExtent(screen[0] - 3, + screen[0] + 3, screen[1] - 3, screen[1] + 3), + color, 1.0f, 1.0); + } + + // Connects adjacent data points with a line + if (prevScreen != null) { + OutlineCapability lineCap = getCapability(OutlineCapability.class); + target.drawLine(screen[0], screen[1], 0.0, prevScreen[0], + prevScreen[1], 0.0, color, + lineCap.getOutlineWidth(), lineCap.getLineStyle()); + } + + prevScreen = screen; + } + + target.clearClippingPlane(); + + /* + * draw delts data + */ + // IFont unitsFont = target.initializeFont((String) null, 14.0f, + // new IFont.Style[] {}); + // target.drawString(unitsFont, this.getBaseline(), + // graph.getExtent() + // .getMaxX() + 100, graph.getExtent().getMinY() - 100, 0.0, + // TextStyle.DROP_SHADOW, RGBColors.getRGBColor("orange"), + // HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM, 0.0); + + } + + /* + * display k-index view + */ + KTableView kTableWin = KTableView.getAccess(); + if (kTableWin != null && kTableWin.getEditorVisible()) { + + KTableView kTableViewWin = KTableView.getAccess(); + + if (kTableViewWin != null) { + AbstractEditor editor = NcDisplayMngr + .getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); + NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane + .getRenderableDisplay(); + + NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane + .getRenderableDisplay(); + + if (activeDisplay.getPaneId().equals(currDisplay.getPaneId())) + + kTableViewWin.paintKTable(magRecords); + } + } + + /* + * display Readout view + */ + SamplingView samplinWin = SamplingView.getAccess(); + if (samplinWin != null && samplinWin.getEditorVisible()) { + + SamplingView samplingViewWin = SamplingView.getAccess(); + + if (samplingViewWin != null) { + AbstractEditor editor = NcDisplayMngr + .getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); + NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane + .getRenderableDisplay(); + + NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane + .getRenderableDisplay(); + + if (activeDisplay.getPaneId().equals(currDisplay.getPaneId())) { + + samplingRsc.getResult(target, descriptor, paintProps, + sampleCoord); + } + } + } + } + + protected boolean checkPaneId(NCTimeSeriesDescriptor desc, IDisplayPane pane) { + + NcPaneID paneId = ((NCTimeSeriesRenderableDisplay) desc + .getRenderableDisplay()).getPaneId(); + + NcPaneID newPaneId = ((NCTimeSeriesRenderableDisplay) pane + .getRenderableDisplay()).getPaneId(); + + if (newPaneId.getColumn() == paneId.getColumn() + && newPaneId.getRow() == paneId.getRow()) { + return true; + + } else { + return false; + } + } + + private UnitConverter createDataConverter() { + // yMedian() =0 causes alert + UnitConverter conv = null; + double temp = -0.0001; + + if (yMedian == 0) + conv = new AddConverter(temp); + else + conv = new AddConverter(-1.0 * yMedian); + + return conv; + } + + private double[] getScreenPosition(Object x, Object y) { + double valY = ((Number) y).doubleValue(); + double valX = ((DataTime) x).getValidTime().getTimeInMillis(); + return graph.getGridLocation(valX, valY); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.core.rsc.IVizResource#getName() + */ + @Override + public String getName() { + + StringBuilder sb = new StringBuilder( + ((GeoMagResourceData) resourceData).getStation()); + if (data == null || data.getData().size() == 0) { + sb.append(" "); + sb.append(((GeoMagResourceData) resourceData).getSourceId()); + sb.append(" "); + sb.append(((GeoMagResourceData) resourceData).getYAxesData()); + sb.append(" - NO DATA"); + + } else { + XYData point = data.getData().get(0); + DataTime time = (DataTime) point.getX(); + + dateFmt.format(time.getValidTimeAsDate()); + + sb.append(" "); + sb.append(((GeoMagResourceData) resourceData).getSourceId()); + sb.append(" "); + sb.append(((GeoMagResourceData) resourceData).getYAxesData()); + sb.append(" - Begin: "); + sb.append(time); + + sb.append(" " + this.getBaseline()); + } + + return sb.toString(); + } + + public String getTitle() { + + String yTitle = ((GeoMagResourceData) this.getResourceData()) + .getYAxesTitle(); + return (yTitle); // + " " + baseline); + } + + public String getBaseline() { + + String baseline = ((GeoMagResourceData) this.getResourceData()) + .getYDescription() + " " + String.format("%.1f", yMedian); + + return (baseline); + } + + @Override + public IGraphLabel[] getXRangeData() { + DataTimeLabel[] labels = new DataTimeLabel[dataTimes.size()]; + int i = 0; + for (DataTime time : dataTimes) { + labels[i++] = new DataTimeLabel(time); + } + return labels; + } + + @Override + public IGraphLabel[] getYRangeData() { + double min = this.getMinDataValue(); + double max = this.getMaxDataValue(); + return new DoubleLabel[] { new DoubleLabel(min), new DoubleLabel(max) }; + } + + @Override + public String inspect(ReferencedCoordinate coord) throws VizException { + if (coord == null) + return "No Data"; + + // if (!sampling) + // return ""; + + String inspect = null; + double[] worldCoord = descriptor.pixelToWorld(new double[] { + coord.getObject().x, coord.getObject().y }); + + Coordinate c = ((XyGraphDescriptor) descriptor).getGraphCoordiante( + this, new Coordinate(worldCoord[0], worldCoord[1])); + + if (c != null && data != null) { + + double[] vals = data.inspectXY(c); + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(2); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTimeInMillis((long) c.x); + timeSampleFormat.setCalendar(cal); + + // inspect = nf.format(vals[1]) + // + ((units != null && units.equals("") == false) ? "(" + // + units + ") " : " ") + // + timeSampleFormat.format(cal.getTime()); + + SamplingView samplingViewWin = SamplingView.getAccess(); + + if (samplingViewWin != null) { + AbstractEditor editor = NcDisplayMngr + .getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); + NCTimeSeriesRenderableDisplay activeDisplay = (NCTimeSeriesRenderableDisplay) activePane + .getRenderableDisplay(); + + NCTimeSeriesRenderableDisplay currDisplay = (NCTimeSeriesRenderableDisplay) currentPane + .getRenderableDisplay(); + + if (activeDisplay.getPaneId().equals(currDisplay.getPaneId())) { + + List hQdcList = new ArrayList(); + List dQdcList = new ArrayList(); + + int hrExtra = (hQdc.length - magRecords.size() + 1) / 60; + int minExtra = hrExtra * 60; + int newSize = hQdc.length - minExtra; + + for (int i = 0; i < newSize; i++) { + hQdcList.add(hQdc[hQdc.length - minExtra + i]); + dQdcList.add(dQdc[dQdc.length - minExtra + i]); + } + + samplingViewWin.paintSampling(magRecords, hQdcList, + dQdcList, cal); + } + } + + } + + return inspect; + } + + @Override + public DataTime[] getDataTimes() { + return dataTimes.toArray(new DataTime[0]); + } + + public double getMinDataValue() { + double min = Double.POSITIVE_INFINITY; + if (data != null) { + for (XYData d : data.getData()) { + if (d.getY() instanceof Number) { + double y = ((Number) d.getY()).doubleValue(); + min = Math.min(min, y); + } + } + } + return min; + } + + public double getMaxDataValue() { + double max = Double.NEGATIVE_INFINITY; + if (data != null) { + for (XYData d : data.getData()) { + if (d.getY() instanceof Number) { + double y = ((Number) d.getY()).doubleValue(); + max = Math.max(max, y); + } + } + } + return max; + } + + @Override + public void redraw() { + + } + +} \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java new file mode 100644 index 0000000000..986d8e6f4d --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/GeoMagResourceData.java @@ -0,0 +1,268 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.rsc.timeseries.rsc; + +import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; +import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsRequestableResourceData; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractNameGenerator; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IPointsToolContainer; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 06/24/2014   #1136       qzhou      Initial creation
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "GeoMagResourceData") +public class GeoMagResourceData extends + AbstractNatlCntrsRequestableResourceData implements + IPointsToolContainer { + + private static final String stationCodeParam = "stationCode"; + + private static final String sourceIdParam = "sourceId"; + + @XmlElement + private String sourceId; + + @XmlElement + private String yAxesData; + + @XmlElement + private String xAxesTitle; + + @XmlElement + private String yAxesTitle; + + @XmlElement + private String yDescription; + + @XmlElement + private String dataColor; + + @XmlElement + private Coordinate coordinate; + + protected DataTime startTime; + + protected DataTime endTime; + + /** + * + */ + public GeoMagResourceData() { + super(); + + // called by AbstractVizResource.getName() + // and we delegate back to the resource + this.nameGenerator = new AbstractNameGenerator() { + + @Override + public String getName(AbstractVizResource resource) { + return ((GeoMagResource) resource).getLegendStr(); + } + }; + } + + @Override + public NcDisplayType[] getSupportedDisplayTypes() { + return new NcDisplayType[] { NcDisplayType.GRAPH_DISPLAY }; + } + + @Override + protected AbstractVizResource constructResource( + LoadProperties loadProperties, PluginDataObject[] objects) + throws VizException { + + return new GeoMagResource(this, loadProperties); + } + + /* + * Copied here from TimeSeriesResourceData since it is declared private. Can + * remove this if changed to protected. + */ + private static final String TIME_SERIES_ADAPTER_EXTENSION = "com.raytheon.uf.viz.xy.timeseries.timeseriesadapter"; + + public String getStation() { + RequestConstraint rc = getMetadataMap().get("stationCode"); + return rc.getConstraintValue(); + } + + @Override + public DataTime[] getAvailableTimes() throws VizException { + DataTime[] times = super.getAvailableTimes(); + // if (updating) { + // this.startTime = calculateStartTime(); + // } + // times = filterTimes(times, startTime, getEndTime()); quan start + // =current time + // System.out.println("START = " + startTime); + // System.out.println(" END = " + getEndTime()); + return times; + } + + /** + * Given the times, filter them to only return times between given times + * + * @param times + * @param start + * @param end + * @return + */ + public DataTime[] filterTimes(DataTime[] times, DataTime startTime, + DataTime endTime) { + List validTimes = new ArrayList(); + for (DataTime time : times) { + if (time.compareTo(startTime) >= 0 && time.compareTo(endTime) <= 0) { + validTimes.add(time); + } + } + return validTimes.toArray(new DataTime[validTimes.size()]); + } + + // private DataTime calculateStartTime() { + // Calendar ttime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // ttime.set(Calendar.MINUTE, 0); + // ttime.set(Calendar.SECOND, 0); + // ttime.set(Calendar.MILLISECOND, 0); + // int currentHour = ttime.get(Calendar.HOUR_OF_DAY); + // // Find next synoptic time as endtime + // int hoursToAdd = 3 - (currentHour % 3); + // ttime.add(Calendar.HOUR_OF_DAY, hoursToAdd); + // // subtract plot length time to get starttime + // ttime.add(Calendar.HOUR_OF_DAY, -plotLengthInHours); + // // long tmilli = ttime.getTimeInMillis(); + // // tmilli -= plotLengthInHours * MILLISECONDS_PER_HOUR; + // + // return new DataTime(ttime.getTime()); + // } + public DataTime getStartTime() { + return startTime; + } + + public void setStartTime(DataTime startTime) { + this.startTime = startTime; + } + + // public boolean isUpdating() { + // return updating; + // } + // + // public void setUpdating(boolean updating) { + // this.updating = updating; + // } + + public String getStationCode() { + return (metadataMap.containsKey(stationCodeParam) ? metadataMap.get( + stationCodeParam).getConstraintValue() : ""); + } + + public String getSourceId() { + return (metadataMap.containsKey(sourceIdParam) ? metadataMap.get( + sourceIdParam).getConstraintValue() : ""); + } + + public String getYAxesData() { + return yAxesData; + } + + public void setYAxesData(String yAxesData) { + this.yAxesData = yAxesData; + } + + public String getXAxesTitle() { + return xAxesTitle; + } + + public void setXAxesTitle(String xAxesTitle) { + this.xAxesTitle = xAxesTitle; + } + + public String getYAxesTitle() { + return yAxesTitle; + } + + public void setYAxesTitle(String yAxesTitle) { + this.yAxesTitle = yAxesTitle; + } + + public String getYDescription() { + return yDescription; + } + + public void setYDescription(String yDescription) { + this.yDescription = yDescription; + } + + public String getDataColor() { + return dataColor; + } + + public void setDataColor(String dataColor) { + this.dataColor = dataColor; + } + + @Override + public void setPointCoordinate(Coordinate pointCoordinate) { + this.coordinate = pointCoordinate; + } + + @Override + public Coordinate getPointCoordinate() { + return coordinate; + } + + @Override + public void setPointLetter(String pointLetter) { + // this.pointLetter = pointLetter; + } + + @Override + public String getPointLetter() { + return null; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/RetrieveUtils.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/RetrieveUtils.java new file mode 100644 index 0000000000..a3862c7f0e --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/RetrieveUtils.java @@ -0,0 +1,220 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.rsc; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagAvg; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; +import gov.noaa.nws.ncep.common.dataplugin.geomag.exception.GeoMagException; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveHrAvgRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveK1minRequest; +import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveSingleK1minRequest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.requests.ThriftClient; + +/** + * + * Utility class containing static methods to retrieve and store PGEN Activities + * in EDEX + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 2014/02/12            qzhou         initiate
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + */ +public class RetrieveUtils { + + /** + * Retrieves the k index + * + * @param stationCode + * @param startTime + * @param endTime + * @return GeoMagK1min record list + * @throws GeoMagException + */ + + @SuppressWarnings("unchecked") + public static List retrieveK1minRecord(String stationCode, + Date startTime, Date endTime) throws GeoMagException { + + RetrieveK1minRequest req = new RetrieveK1minRequest(stationCode, + startTime, endTime); + List resultList = null; + try { + resultList = (List) ThriftClient.sendRequest(req); + } catch (VizException e) { + throw new GeoMagException( + "Unable to retrieve geomag k-index Activities.", e); + } + + return resultList; + } + + @SuppressWarnings("unchecked") + public static List retrieveSingleK1minRecord( + String stationCode, Date startTime) throws GeoMagException { + + RetrieveSingleK1minRequest req = new RetrieveSingleK1minRequest( + stationCode, startTime); + + List resultList = null; + try { + resultList = (List) ThriftClient.sendRequest(req); + + } catch (VizException e) { + throw new GeoMagException( + "Unable to retrieve geomag k-index Activities.", e); + } + + return resultList; + } + + /** + * Retrieves the hHrAvg and dHrAvg + * + * @param stationCode + * @param startTime + * @param endTime + * @return avgList + * @throws GeoMagException + */ + @SuppressWarnings("unchecked") + public static List retrieveHrAvgs(String stationCode, + Date startTime, Date endTime) throws GeoMagException { + + List avgList = new ArrayList(); + + try { + RetrieveHrAvgRequest request = new RetrieveHrAvgRequest( + stationCode, startTime, endTime);// startTime-1 + avgList = (List) ThriftClient.sendRequest(request); + + } catch (Exception e) { + throw new GeoMagException( + "Unable to retrieve geomag average Activities.", e); + + } + + return avgList; + + } + + // @SuppressWarnings("unchecked") + // public static List retrieveGeoMag(String stationCode, + // Date startTime, Date endTime) throws GeoMagException { + // + // List geoMagList = new ArrayList(); + // + // try { + // RetrieveGeoMagRequest request = new RetrieveGeoMagRequest( + // stationCode, startTime, endTime); + // geoMagList = (List) ThriftClient.sendRequest(request); + // + // } catch (Exception e) { + // throw new GeoMagException( + // "Unable to retrieve geomag average Activities.", e); + // + // } + // + // return geoMagList; + // + // } + + public static Date getUtcDate(Calendar cal) { + // cal in GMT timezone + TimeZone z = TimeZone.getDefault(); + int offset = z.getOffset(cal.getTimeInMillis()); + + Date date = new Date(cal.getTimeInMillis() - offset); + + return date; + } + + public static Calendar getUtcCalendar(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("GMT")); + + calendar.setTimeInMillis(date.getTime()); + + return calendar; + } + + public static String hourTo2DigetStr(Calendar calendar) { + int hour = calendar.get(Calendar.HOUR_OF_DAY); + + if (hour == 24) + hour = 0; + + String hourStr = String.valueOf(hour); + + if (hourStr.length() == 1) + hourStr = '0' + hourStr; + + return hourStr; + } + + public static Calendar moveToNextSynop(Calendar cal, int synop) { + Calendar calendar = (Calendar) cal.clone(); + calendar.add(Calendar.HOUR_OF_DAY, synop); + + return calendar; + } + + public static DataTime moveToNextSynop(DataTime dataTime, int synop) { + Calendar cal = dataTime.getValidTime(); + Calendar calendar = moveToNextSynop(cal, synop); + DataTime newDataTime = new DataTime(calendar); + + return newDataTime; + } + + public static float[] getMedian(List records) { + + if (records == null || records.size() == 0) + return new float[] { 0f, 0f }; + + int size = records.size(); + float[] hComps = new float[size]; + float[] dComps = new float[size]; + + for (int i = 0; i < size; i++) { + hComps[i] = records.get(i).getComponent_1(); + dComps[i] = records.get(i).getComponent_2(); + } + + Arrays.sort(hComps); + Arrays.sort(dComps); + + float hMedian = 0f; + float dMedian = 0f; + + if (size % 2 == 0) { + hMedian = (hComps[hComps.length / 2] + hComps[hComps.length / 2 - 1]) / 2; + dMedian = (dComps[dComps.length / 2] + dComps[dComps.length / 2 - 1]) / 2; + + } else { + hMedian = hComps[(hComps.length - 1) / 2]; + dMedian = dComps[(dComps.length - 1) / 2]; + } + + return new float[] { hMedian, dMedian }; + + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/Sampling.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/Sampling.java new file mode 100644 index 0000000000..63ca751b9c --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/Sampling.java @@ -0,0 +1,481 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.rsc.timeseries.rsc; + +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource.ResourceStatus; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Sampling resource, draws sample text to the screen. also picks up mouse + * events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer         Description
+ * ------------ ---------- -----------      --------------------------
+ * 07/21/2014   R4079      qzhou            Initial creation
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + */ + +public class Sampling { + + /** + * The result of a hover operation: a set of strings and corresponding + * colors + * + */ + protected static class SampleResult { + + public SampleResult() { + + } + + public String[] labels; + + public RGB[] colors; + } + + private IFont hoverFont = null; + + private boolean errorInHovering = false; + + private VerticalAlignment verticalAlignment = VerticalAlignment.TOP; + + public Sampling() { + + } + + protected SampleResult doHover(ReferencedCoordinate coord, + ResourceList resources) throws VizException { + SampleResult result = new SampleResult(); + List labelList = new ArrayList(); + List colorList = new ArrayList(); + try { + int size = resources.size(); + + for (int i = size - 1; i >= 0; --i) { + ResourcePair rp = resources.get(i); + String retVal = recursiveHoverSearch(rp, coord); + + if (retVal != null && retVal.length() > 0) { + + RGB color = null; + if (rp.getResource().hasCapability( + ColorableCapability.class)) { + color = rp.getResource() + .getCapability(ColorableCapability.class) + .getColor(); + } + int p1, p2; + p1 = 0; + while ((p2 = retVal.indexOf('\n', p1)) >= 0) { + colorList.add(color); + labelList.add(retVal.substring(p1, p2)); + p1 = p2 + 1; + } + String s = retVal.substring(p1); + if (s.length() > 0) { + colorList.add(color); + labelList.add(retVal.substring(p1)); + } + + break; + } + } + } catch (Throwable t) { + /* + * statusHandler.handle(Priority.PROBLEM, + * "Error sampling resources: " + t.getLocalizedMessage(), t); + */ + } + + result.labels = labelList.toArray(new String[labelList.size()]); + result.colors = colorList.toArray(new RGB[colorList.size()]); + return result; + } + + private String recursiveHoverSearch(ResourcePair rp, + ReferencedCoordinate coordinate) throws VizException { + ResourceProperties props = rp.getProperties(); + AbstractVizResource rsc = rp.getResource(); + + if (rsc != null && rsc.getStatus() == ResourceStatus.INITIALIZED + && props.isVisible()) { + String curVal = rsc.inspect(coordinate); + + if (curVal != null && curVal.length() > 0) { + return curVal; + } + } + + return null; + } + + /** + * Display sampling on a view, or not on the original screen. + */ + protected void getResult(IGraphicsTarget target, IDescriptor descriptor, + PaintProperties paintProps, ReferencedCoordinate coord) + throws VizException { + if (hoverFont == null) { + hoverFont = target.initializeFont(target.getDefaultFont() + .getFontName(), 10, null); + hoverFont.setSmoothing(false); + hoverFont.setScaleFont(false); + } + + doHover(coord, descriptor.getResourceList()); + + } + + /** + * Display sampling on the original screen. + */ + protected void paintResult(IGraphicsTarget target, IDescriptor descriptor, + PaintProperties paintProps, ReferencedCoordinate coord) + throws VizException { + if (hoverFont == null) { + hoverFont = target.initializeFont(target.getDefaultFont() + .getFontName(), 10, null); + hoverFont.setSmoothing(false); + hoverFont.setScaleFont(false); + } + + SampleResult result = doHover(coord, descriptor.getResourceList()); + + verticalAlignment = VerticalAlignment.TOP; + target.clearClippingPlane(); + try { + if (result != null) { + double[] world = new double[] { coord.getObject().x, + coord.getObject().y }; + double[] pixel = descriptor.worldToPixel(world); + Coordinate c = new Coordinate(pixel[0], pixel[1]); + int canvasWidth = paintProps.getCanvasBounds().width; + double extentWidth = paintProps.getView().getExtent() + .getWidth(); + double ratioX = canvasWidth / extentWidth; + + if (result.labels.length > 0) { + List strsToUse = new ArrayList(); + List colorsToUse = new ArrayList(); + HorizontalAlignment[] alignments = new HorizontalAlignment[result.labels.length]; + boolean[] modified = new boolean[result.labels.length]; + for (int i = 0; i < modified.length; ++i) { + modified[i] = false; + alignments[i] = HorizontalAlignment.LEFT; + String[] tmp = new String[] { result.labels[i], + result.labels[i] }; + strsToUse.add(tmp); + } + + adjustStrings(target, paintProps, strsToUse, modified, + alignments, c, ratioX, null); + + HorizontalAlignment horizontalAlignment = alignments[0]; + boolean good = true; + for (int i = 1; i < alignments.length && good; ++i) { + if (horizontalAlignment != alignments[i]) { + good = false; + } + } + + if (!good) { + // not all the same, figure out alignments!!! + int maxLen = 0; + int i = 0; + for (String[] s : strsToUse) { + if (s[0].length() > maxLen) { + maxLen = s[0].length(); + horizontalAlignment = alignments[i]; + } + ++i; + } + + adjustStrings(target, paintProps, strsToUse, modified, + alignments, c, ratioX, horizontalAlignment); + } + + List actualStrs = new ArrayList(); + for (int i = 0; i < strsToUse.size(); ++i) { + String[] strs = strsToUse.get(i); + for (int j = 1; j < strs.length; ++j) { + actualStrs.add(strs[j]); + colorsToUse.add(result.colors[i]); + } + } + + String[] newStrs = actualStrs.toArray(new String[actualStrs + .size()]); + + double referencePtY = adjustLabelWrapY( + target, + newStrs, + c.y + + ((AbstractRenderableDisplay.CURSOR_HEIGHT) / ratioX), + paintProps.getView().getExtent(), ratioX); + + if (horizontalAlignment == HorizontalAlignment.RIGHT) { + c.x -= (target.getStringBounds(hoverFont, newStrs, + TextStyle.BLANKED).getWidth() / ratioX); + } + + target.drawStrings(hoverFont, newStrs, c.x, referencePtY, + 0.0, IGraphicsTarget.TextStyle.BLANKED, + colorsToUse.toArray(new RGB[colorsToUse.size()]), + HorizontalAlignment.LEFT, verticalAlignment); + } + } + errorInHovering = false; + } catch (Exception e) { + // if (errorInHovering) { + // // Keep down the number of error messages + // /* + // * statusHandler.handle( Priority.PROBLEM, + // * "Error painting sample text: " + e.getLocalizedMessage(), e); + // */ + // } + errorInHovering = true; + } + } + + private void adjustStrings(IGraphicsTarget target, + PaintProperties paintProps, List strsToUse, + boolean[] modified, HorizontalAlignment[] alignments, Coordinate c, + double ratio, HorizontalAlignment targetAlignment) { + List strsToUseInternal = new ArrayList(); + for (int i = 0; i < strsToUse.size(); ++i) { + String str = strsToUse.get(i)[0]; + String[] split = str.split("[ ]"); + boolean done = false; + int divideBy = strsToUse.get(i).length - 1; + int maxDivisions = 0; + for (int j = 0; j < split.length; ++j) { + if (split[j].isEmpty() == false) { + ++maxDivisions; + } + } + + if (alignments[i] == targetAlignment) { + strsToUseInternal.add(strsToUse.get(i)); + } else { + String[] test = new String[] { str }; + while (!done) { + if (divideBy > maxDivisions + || alignments[i] == targetAlignment) { + done = true; + continue; + } + + int approxLenPerStr = str.length() / divideBy; + List strs = new ArrayList(); + + for (int j = 0; j < split.length;) { + String line = split[j++]; + while (j < split.length) { + String s = split[j]; + if (s.length() + line.length() <= approxLenPerStr) { + if (!s.isEmpty()) { + if (j == split.length - 1 + && split[1].equalsIgnoreCase("=")) { + line = split[split.length - 1]; + } else { + line += " " + s; + } + } else { + line += " "; + } + ++j; + } else { + break; + } + } + strs.add(line); + } + + test = strs.toArray(new String[strs.size()]); + + HorizontalAlignment alignment = adjustLabelWrapX(target, + test, c.x, paintProps.getView().getExtent(), ratio, + alignments[i]); + if (alignment == alignments[i] + && (targetAlignment == null || alignment == targetAlignment)) { + // the alignment was not changed and we are the target + // alignment, we are done + done = true; + } else { + if (targetAlignment == null) { + // alignment changed, check to see if it changes + // back + HorizontalAlignment tmpAlignment = alignment; + alignment = adjustLabelWrapX(target, test, c.x, + paintProps.getView().getExtent(), ratio, + alignment); + if (alignment != tmpAlignment) { + // we moved back, we need to divide and + // conquer + alignments[i] = HorizontalAlignment.LEFT; + modified[i] = true; + divideBy++; + } else { + // we are good at this alignment + alignments[i] = alignment; + done = true; + } + } else { + // we need to be the targetAlignment + alignment = adjustLabelWrapX(target, test, c.x, + paintProps.getView().getExtent(), ratio, + targetAlignment); + if (alignment == targetAlignment) { + // we are fine at other alignment also, use it: + alignments[i] = alignment; + done = true; + } else { + alignments[i] = targetAlignment; + modified[i] = true; + divideBy++; + } + } + } + } + + String[] addTo = new String[test.length + 1]; + addTo[0] = str; + for (int j = 0; j < test.length; ++j) { + addTo[j + 1] = test[j]; + } + + strsToUseInternal.add(addTo); + } + } + strsToUse.clear(); + strsToUse.addAll(strsToUseInternal); + } + + /** + * Adjusts the x label if the width of the longest label extends the extent + * + * @param target + * @param labels + * @param x + * @param extent + * @param ratio + * @return + */ + private HorizontalAlignment adjustLabelWrapX(IGraphicsTarget target, + String[] labels, double x, IExtent extent, double ratio, + HorizontalAlignment horizontalAlignment) { + double referencePoint = x; + + // Find the max width of the label in pixels + double maxWidth = 0; + IFont font = hoverFont; + for (String label : labels) { + Rectangle2D bounds = target.getStringBounds(font, label); + if (bounds.getWidth() > maxWidth) { + maxWidth = bounds.getWidth(); + } + } + + // Get the width in gl space + double widthInGl = maxWidth / ratio; + + if (horizontalAlignment == HorizontalAlignment.LEFT) { + // Check to see if text extends screen extent + if (referencePoint + widthInGl > extent.getMaxX()) { + horizontalAlignment = HorizontalAlignment.RIGHT; + } + } else { + // Check to see if text extends screen extent + if (referencePoint - widthInGl < extent.getMinX()) { + horizontalAlignment = HorizontalAlignment.LEFT; + } + } + + return horizontalAlignment; + } + + /** + * Adjusts the y label position if the stacked labels exceeds the screen + * extent height + * + * @param target + * @param labels + * @param y + * @param extent + * @param ratio + * @return + */ + private double adjustLabelWrapY(IGraphicsTarget target, String[] labels, + double y, IExtent extent, double ratio) { + double referencePoint = y; + + double totalHeight = target.getStringBounds(hoverFont, labels, + TextStyle.BLANKED).getHeight(); + + // convert to gl space + double maxHeightInGl = (totalHeight) / ratio; + + // check to see if height extends map height + if (referencePoint + maxHeightInGl > extent.getMaxY()) { + verticalAlignment = VerticalAlignment.BOTTOM; + referencePoint -= (AbstractRenderableDisplay.CURSOR_HEIGHT + 2) + / ratio; + } + + // return adjusted point + return referencePoint; + } + + public void dispose() { + if (hoverFont != null) { + hoverFont.dispose(); + } + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java new file mode 100644 index 0000000000..c6d53a49f7 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/rsc/SamplingInputAdapter.java @@ -0,0 +1,155 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.rsc.timeseries.rsc; + +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; + +import org.eclipse.swt.widgets.Event; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.raytheon.viz.ui.input.InputAdapter; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Default input handler for timeseries/geomag sampling + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 07/16/2014   R4079      qzhou       Initial creation
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + */ + +public class SamplingInputAdapter extends + InputAdapter { + + private T resource; + + public SamplingInputAdapter(T resource) { + this.resource = resource; + } + + @Override + public boolean handleMouseMove(int x, int y) { + + IDisplayPaneContainer container = resource.getResourceContainer(); + Coordinate c = container.translateClick(x, y); + + boolean isActiveResource = false; + + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + IDisplayPane activePane = editor.getActiveDisplayPane(); + + ResourceList acResources = activePane.getDescriptor().getResourceList(); + int acRscSize = acResources.size(); + + for (int i = acRscSize - 1; i >= 0; i--) { + ResourcePair rp = acResources.get(i); + AbstractVizResource activeRsc = rp.getResource(); + + if (activeRsc != null + && activeRsc instanceof GeoMagResource + && rp.getProperties().isVisible() + && !((GeoMagResource) activeRsc).getLegendStr().equals( + "No Data")) { + + if (activeRsc.equals(resource)) { + isActiveResource = true; + } + break; + } + + } + + if (resource.getResourceContainer().getDisplayPanes().length > 1) { + // Coordinate latLonCoord = ((GeoMagResource) resource) + // .getLatLonFromPixel(c); + + for (IDisplayPane pane : resource.getResourceContainer() + .getDisplayPanes()) { + + if (!pane.equals(activePane) && isActiveResource) { + + ResourceList resources = pane.getDescriptor() + .getResourceList(); + int size = resources.size(); + + for (int i = 0; i < size && size > 1; i++) { + ResourcePair rp = resources.get(i); + AbstractVizResource rsc = rp.getResource(); + + if (rsc != null && rsc instanceof GeoMagResource + && rp.getProperties().isVisible()) { + // ((GeoMagResource) rsc) + // .setVirtualCursor(latLonCoord); + + ((GeoMagResource) rsc).issueRefresh(); + + } + } + } + } + } + + if (isActiveResource) { + if (c != null) { + resource.sampleCoord = new ReferencedCoordinate(c); + } else { + resource.sampleCoord = null; + } + } + + // The sampling is always true for geomag + resource.issueRefresh(); + + return false; + } + + @Override + public boolean handleMouseDownMove(int x, int y, int mouseButton) { + return handleMouseMove(x, y); + } + + public boolean handleMouseExit(Event event) { + resource.sampleCoord = null; + // resource.virtualCursor = null; + + resource.issueRefresh(); + + return false; + } + + public boolean handleMouseEnter(Event event) { + return handleMouseMove(event.x, event.y); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/KTableAction.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/KTableAction.java new file mode 100644 index 0000000000..c4641f9370 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/KTableAction.java @@ -0,0 +1,59 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.view; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +/** + * + * KTableView Action for GeoMagResource + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ * 07/07/2014    R4079       qzhou     Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ +public class KTableAction extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + /* + * The viewID string is in the XML file for extension point. + */ + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(KTableView.kTableId); + + try { + + if (vpart == null) { + vpart = wpage.showView(KTableView.kTableId); + + } else { + if (!wpage.isPartVisible(vpart)) + vpart = wpage.showView(KTableView.kTableId); + + } + } catch (Exception e) { + + e.printStackTrace(); + + } + + return null; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/KTableView.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/KTableView.java new file mode 100644 index 0000000000..205d454cce --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/KTableView.java @@ -0,0 +1,394 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.view; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min; +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; +import gov.noaa.nws.ncep.common.dataplugin.geomag.exception.GeoMagException; +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.RetrieveUtils; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + +/** + * + * Display KTableView for GeoMagResource + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ * 07/07/2014    R4079       qzhou     Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ +public class KTableView extends ViewPart implements SelectionListener, + DisposeListener, IPartListener { + + public static final String kTableId = "gov.noaa.nws.ncep.viz.rsc.timeseries.view.KTableView";// + + public Composite composite = null; + + private Text text; + + private boolean isEditorVisible = true; + + private static KTableView kTableView = null; + + public static KTableView getAccess() { + return kTableView; + } + + public KTableView() { + + super(); + if (kTableView == null) + kTableView = this; + else { + KTableView tmp = kTableView; + kTableView = this; + + } + } + + /** + * Invoked by the workbench to initialize this View. + */ + public void init(IViewSite site) { + try { + super.init(site); + + } catch (PartInitException pie) { + + pie.printStackTrace(); + } + + // GeoMagResource.registerMouseHandler(); + // page = site.getPage(); + // page.addPartListener(this); + + } + + /** + * Disposes resource. invoked by the workbench + */ + public void dispose() { + + if (!isEditorVisible) { + // GeoMagResource.unregisterMouseHandler(); + return; + } else { + super.dispose(); + + // NatlCntrsEditor editor = GeoMagResource.getMapEditor(); + // + // if (editor != null) { + // for (IRenderableDisplay display : UiUtil + // .getDisplaysFromContainer(editor)) { + // // System.out.println("display " + display.toString()); + // for (ResourcePair rp : display.getDescriptor() + // .getResourceList()) { + // if (rp.getResource() instanceof GeoMagResource) { + // GeoMagResource rsc = (GeoMagResource) rp + // .getResource(); + // rsc.unload(); + // } + // } + // } + // } + kTableView = null; + + /* + * remove the workbench part listener + */ + // page.removePartListener(this); + } + + } + + private void close() { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(kTableId); + wpage.hideView(vpart); + + NcDisplayMngr.setPanningMode(); + } + + @Override + public void createPartControl(Composite parent) { + + parent.setLayout(new GridLayout(1, false)); + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, + 1)); + composite.setLayout(new GridLayout(2, false)); + + createTextArea(composite); + + } + + public void createTextArea(Composite parent) { + // Text display area + text = new Text(parent, SWT.V_SCROLL | SWT.H_SCROLL); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + text.setLayoutData(data); + + Font font = text.getFont(); + FontData[] fontData = font.getFontData(); + for (int i = 0; i < fontData.length; i++) { + fontData[i].setStyle(1); + fontData[i].setName("courier"); + } + Font newFont = new Font(font.getDevice(), fontData); + text.setFont(newFont); + text.setEditable(false); + + // RGB color = RGBColors.getRGBColor("black"); + // Device device = parent.getDisplay(); + // text.setBackground(new Color(device, color)); + + } + + public void paintKTable(List recordsList) { + + text.setText(""); + List kList = getKValues(recordsList); + + // Add title to kList + String t0 = " "; + String t1 = " K "; + String t2 = " Gamma "; + String t3 = " HK "; + String t4 = " H-Gamma "; + String t5 = " DK "; + String t6 = " D-Gamma "; + + // StringBuffer drawStrings = new StringBuffer(); + + for (int j = 0; j < 7; j++) { + // add title for each j + if (j == 0) + text.append(t0); + else if (j == 1) + text.append(t1); + else if (j == 2) + text.append(t2); + else if (j == 3) + text.append(t3); + else if (j == 4) + text.append(t4); + else if (j == 5) + text.append(t5); + else if (j == 6) + text.append(t6); + + // add rest for each j. + for (int i = 0; i < kList.size(); i++) { + String[] drawStr = kList.get(i); + text.append(String.format("%12s", drawStr[j])); + + } + text.append("\n"); + + } + + // text.setText(drawStrings.toString()); + text.setVisible(true); + + } + + public List getKValues(List recordsList) { + List k1minList = null; + List kList = new ArrayList(); + + Calendar synTime = null; + + for (int i = 1; i < recordsList.size(); i++) { // omit the first + + Calendar calInstant = recordsList.get(i).getDataTime() + .getValidTime(); + if (i == recordsList.size() - 1) { + if (calInstant.get(Calendar.MINUTE) == 0) + synTime = recordsList.get(recordsList.size() - 2) + .getDataTime().getValidTime(); + else + synTime = recordsList.get(recordsList.size() - 1) + .getDataTime().getValidTime(); + + try { + k1minList = RetrieveUtils.retrieveSingleK1minRecord( + recordsList.get(0).getStationCode(), new Date( + synTime.getTimeInMillis())); // RetrieveUtils.getUtcTime(synTime)); + + } catch (GeoMagException e) { + System.out + .println("GeoMag KTableView: Error retrieving k1min record."); + } + + if (k1minList != null && k1minList.size() > 0) { + GeoMagK1min k1min = k1minList.get(0); + String[] temp = new String[7]; + + Date d = k1min.getRefTime(); + Calendar cal = RetrieveUtils.getUtcCalendar(d); + + // deal with recordsList.size() + if (cal.get(Calendar.MINUTE) != 0) { + if (cal.get(Calendar.HOUR_OF_DAY) % 3 == 1) + cal.add(Calendar.HOUR_OF_DAY, 2); + else if (cal.get(Calendar.HOUR_OF_DAY) % 3 == 2) + cal.add(Calendar.HOUR_OF_DAY, 1); + + cal.set(Calendar.MINUTE, 0); + } + String end = RetrieveUtils.hourTo2DigetStr(cal); + // minus 3 hour becomes previous synaptic point + cal.add(Calendar.HOUR_OF_DAY, -3); + String start = RetrieveUtils.hourTo2DigetStr(cal); + + temp[0] = start + " - " + end; + temp[1] = String.valueOf(k1min.getKestIndex()); + temp[2] = String.valueOf((int) k1min.getKestGamma()); + temp[3] = String.valueOf(k1min.getHkIndex()); + temp[4] = String.valueOf((int) k1min.getHkGamma()); + temp[5] = String.valueOf(k1min.getDkIndex()); + temp[6] = String.valueOf((int) k1min.getDkGamma()); + kList.add(temp); + } + + } else if (!(calInstant.get(Calendar.HOUR_OF_DAY) % 3 == 0 && calInstant + .get(Calendar.MINUTE) == 0)) { + synTime = calInstant; + + } else { + + try { + k1minList = RetrieveUtils.retrieveSingleK1minRecord( + recordsList.get(0).getStationCode(), new Date( + synTime.getTimeInMillis())); // RetrieveUtils.getUtcTime(synTime)); + + } catch (GeoMagException e) { + System.out + .println("GeoMag KTableView: Error retrieving k1min record."); + } + + if (k1minList != null && k1minList.size() > 0) { + GeoMagK1min k1min = k1minList.get(0); + String[] temp = new String[7]; + + Date d = k1min.getRefTime(); + Calendar cal = RetrieveUtils.getUtcCalendar(d); + + // adding 1 minute becomes next synaptic point + cal.add(Calendar.MINUTE, 1); + String end = RetrieveUtils.hourTo2DigetStr(cal); + // minus 3 hour becomes previous synaptic point + cal.add(Calendar.HOUR_OF_DAY, -3); + String start = RetrieveUtils.hourTo2DigetStr(cal); + + temp[0] = start + " - " + end; + temp[1] = String.valueOf(k1min.getKestIndex()); + temp[2] = String.valueOf((int) k1min.getKestGamma()); + temp[3] = String.valueOf(k1min.getHkIndex()); + temp[4] = String.valueOf((int) k1min.getHkGamma()); + temp[5] = String.valueOf(k1min.getDkIndex()); + temp[6] = String.valueOf((int) k1min.getDkGamma()); + kList.add(temp); + } + } + } + + return kList; + } + + public Text getText() { + return text; + } + + public void setText(Text text) { + this.text = text; + } + + @Override + public void setFocus() { + + } + + @Override + public void partActivated(IWorkbenchPart part) { + + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + + } + + @Override + public void partClosed(IWorkbenchPart part) { + + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + + } + + @Override + public void partOpened(IWorkbenchPart part) { + + } + + @Override + public void widgetDisposed(DisposeEvent e) { + + } + + @Override + public void widgetSelected(SelectionEvent e) { + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + public void setEditorVisible(boolean isVisible) { + this.isEditorVisible = isVisible; + } + + public boolean getEditorVisible() { + return this.isEditorVisible; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/SamplingAction.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/SamplingAction.java new file mode 100644 index 0000000000..68c4a4c7fc --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/SamplingAction.java @@ -0,0 +1,59 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.view; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; + +/** + * + * Sampling readout Action for GeoMagResource + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ * 07/07/2014    R4079       qzhou     Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ +public class SamplingAction extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + /* + * The viewID string is in the XML file for extension point. + */ + + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(SamplingView.samplingId); + + try { + + if (vpart == null) { + vpart = wpage.showView(SamplingView.samplingId); + + } else { + if (!wpage.isPartVisible(vpart)) + vpart = wpage.showView(SamplingView.samplingId); + + } + } catch (Exception e) { + + e.printStackTrace(); + + } + + return null; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/SamplingView.java b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/SamplingView.java new file mode 100644 index 0000000000..34886bb0f4 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.rsc.timeseries/src/gov/noaa/nws/ncep/viz/rsc/timeseries/view/SamplingView.java @@ -0,0 +1,374 @@ +package gov.noaa.nws.ncep.viz.rsc.timeseries.view; + +import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagRecord; +import gov.noaa.nws.ncep.viz.rsc.timeseries.rsc.RetrieveUtils; +import gov.noaa.nws.ncep.viz.ui.display.NcDisplayMngr; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + +/** + * + * Display sampling readout for GeoMagResource + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ * 07/07/2014    R4079       qzhou     Initial Creation.
+ * 
+ * 
+ * + * @author qzhou + * @version 1 + */ + +public class SamplingView extends ViewPart implements SelectionListener, + DisposeListener, IPartListener { + + public static final String samplingId = "gov.noaa.nws.ncep.viz.rsc.timeseries.view.SamplingView"; + + public Composite composite = null; + + private StyledText text; + + private boolean isEditorVisible = true; + + private static SamplingView samplingView = null; + + private Device device; + + private Color textColor; + + private Color currColor; + + private final SimpleDateFormat timeSampleFormat = new SimpleDateFormat( + "yyyy/MM/dd'T'HH':'mm"); + + public static SamplingView getAccess() { + return samplingView; + } + + public SamplingView() { + + super(); + if (samplingView == null) + samplingView = this; + else { + SamplingView tmp = samplingView; + samplingView = this; + } + } + + /** + * Invoked by the workbench to initialize this View. + */ + public void init(IViewSite site) { + try { + super.init(site); + + } catch (PartInitException pie) { + + pie.printStackTrace(); + } + + } + + /** + * Disposes resource. invoked by the workbench + */ + public void dispose() { + + if (!isEditorVisible) { + // GeoMagResource.unregisterMouseHandler(); + return; + } else { + super.dispose(); + + // NatlCntrsEditor editor = GeoMagResource.getMapEditor(); + // + // if (editor != null) { + // for (IRenderableDisplay display : UiUtil + // .getDisplaysFromContainer(editor)) { + // // System.out.println("display " + display.toString()); + // for (ResourcePair rp : display.getDescriptor() + // .getResourceList()) { + // if (rp.getResource() instanceof GeoMagResource) { + // GeoMagResource rsc = (GeoMagResource) rp + // .getResource(); + // rsc.unload(); + // } + // } + // } + // } + samplingView = null; + + // remove the workbench part listener + // page.removePartListener(this); + } + + } + + private void close() { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + + IViewPart vpart = wpage.findView(samplingId); + wpage.hideView(vpart); + + NcDisplayMngr.setPanningMode(); + } + + @Override + public void createPartControl(Composite parent) { + + parent.setLayout(new GridLayout(1, false)); + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, + 1)); + composite.setLayout(new GridLayout(2, false)); + + createTextArea(composite); + + } + + public void createTextArea(Composite parent) { + // Text display area + text = new StyledText(parent, SWT.V_SCROLL | SWT.H_SCROLL); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + text.setLayoutData(data); + + Font font = text.getFont(); + FontData[] fontData = font.getFontData(); + + for (int i = 0; i < fontData.length; i++) { + // fontData[i].setHeight(12); + fontData[i].setName("courier"); + fontData[i].setStyle(1); + } + + Font newFont = new Font(font.getDevice(), fontData); + text.setFont(newFont); + + text.setEditable(false); + + device = parent.getDisplay(); + textColor = new Color(device, 0, 0, 0); // RGBColors.getRGBColor("black")); + currColor = new Color(device, 255, 0, 0); // RGBColors.getRGBColor("red")); + + } + + public void paintSampling(List recordsList, + List hQdcList, List dQdcList, Calendar cal) { + + StyleRange[] styleRanges = new StyleRange[2]; + + List list = new ArrayList(); + List geoMagList = getSamplingRecords(recordsList, cal); + + // hdev = h_data91440:2879] - h_qdc + List devList = getSamplingDevs(recordsList, hQdcList, + dQdcList, cal); + + float[] median = RetrieveUtils.getMedian(recordsList); + String timeStr = timeSampleFormat.format(RetrieveUtils.getUtcDate(cal)); + + text.setText(""); + text.append(" Readout H D HDev DDev\n"); + + for (int i = 0; i < geoMagList.size(); i++) { + GeoMagRecord geomag = geoMagList.get(i); + String[] temp = new String[5]; + + Calendar calendar = geomag.getDataTime().getValidTime(); + temp[0] = timeSampleFormat.format(RetrieveUtils + .getUtcDate(calendar)); + temp[1] = String.format("%6.1f", + (geomag.getComponent_1() - median[0])); + temp[2] = String.format("%6.1f", + (geomag.getComponent_2() - median[1])); + temp[3] = String.format("%6.1f", + (geomag.getComponent_1() - devList.get(i)[0])); + temp[4] = String.format("%6.1f", + (geomag.getComponent_2() - devList.get(i)[1])); + // testing + // temp[3] = String.format("%.1f", (devList.get(i)[0] - median[0])); + // temp[4] = String.format("%.1f", (devList.get(i)[1] - median[1])); + list.add(temp); + } + + int textLength = 0; + // print the list. + for (int i = 0; i < list.size(); i++) { + String[] drawStr = list.get(i); + + for (int j = 0; j < 5; j++) { + if (j == 0) { + // add indent + if (list.get(i)[0].equals(timeStr)) { + textLength = text.getText().length(); + + text.append("=>" + drawStr[j]); + } else { + + text.append(" " + drawStr[j]); + } + } else { + // text.append(String.format("%6s", drawStr[j])); + text.append(drawStr[j]); + } + } + text.append("\n"); + + } + + styleRanges[0] = new StyleRange(0, textLength, currColor, null); + styleRanges[1] = new StyleRange(textLength, + text.getText().length() + 1, textColor, null); + + // text.setText(text.getText()); + text.setStyleRanges(styleRanges); + text.setVisible(true); + + } + + public List getSamplingDevs(List recordsList, + List hQdcList, List dQdcList, Calendar cal) { + List devList = new ArrayList(); + + // according to cal, build displaying List devList, + // which is 14 minutes before and after cal + Calendar calStart = (Calendar) cal.clone(); + calStart.add(Calendar.MINUTE, -14 - 1); // seconds and round to 1min + Calendar calEnd = (Calendar) cal.clone(); + calEnd.add(Calendar.MINUTE, 14); + + for (int i = 0; i < recordsList.size(); i++) { + if (recordsList.get(i).getDataTime().getValidTime() + .getTimeInMillis() >= calStart.getTimeInMillis() + && recordsList.get(i).getDataTime().getValidTime() + .getTimeInMillis() <= calEnd.getTimeInMillis()) { + + float hTemp = hQdcList.get(i); + float dTemp = dQdcList.get(i); + devList.add(new float[] { hTemp, dTemp }); + } + } + + return devList; + } + + public List getSamplingRecords( + List recordsList, Calendar cal) { + + // according to cal, build displaying List sampRecord, + // which is 14 minutes before and after cal + Calendar calStart = (Calendar) cal.clone(); + calStart.add(Calendar.MINUTE, -14 - 1); // seconds and round to 1min + Calendar calEnd = (Calendar) cal.clone(); + calEnd.add(Calendar.MINUTE, 14); + // System.out.println("**start " + calStart + " " + calEnd); + + List sampRecord = new ArrayList(); + for (int i = 0; i < recordsList.size(); i++) { + if (recordsList.get(i).getDataTime().getValidTime() + .getTimeInMillis() >= calStart.getTimeInMillis() + && recordsList.get(i).getDataTime().getValidTime() + .getTimeInMillis() <= calEnd.getTimeInMillis()) + + sampRecord.add(recordsList.get(i)); + } + + return sampRecord; + } + + public StyledText getText() { + return text; + } + + public void setText(StyledText text) { + this.text = text; + } + + @Override + public void setFocus() { + + } + + @Override + public void partActivated(IWorkbenchPart part) { + + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + + } + + @Override + public void partClosed(IWorkbenchPart part) { + + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + + } + + @Override + public void partOpened(IWorkbenchPart part) { + + } + + @Override + public void widgetDisposed(DisposeEvent e) { + + } + + @Override + public void widgetSelected(SelectionEvent e) { + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + public void setEditorVisible(boolean isVisible) { + this.isEditorVisible = isVisible; + } + + public boolean getEditorVisible() { + return this.isEditorVisible; + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.viz.ui.display/META-INF/MANIFEST.MF index eea1dd0915..39cff99306 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/META-INF/MANIFEST.MF @@ -16,12 +16,18 @@ Require-Bundle: org.eclipse.ui, gov.noaa.nws.ncep.viz.localization;bundle-version="1.0.0", com.raytheon.uf.common.style;bundle-version="1.0.0", com.raytheon.viz.core.graphing;bundle-version="1.12.1174", - com.raytheon.uf.viz.core.maps;bundle-version="1.12.1174" + com.raytheon.uf.viz.core.maps;bundle-version="1.12.1174", + com.raytheon.uf.viz.xy.timeseries, + com.raytheon.uf.viz.xy;bundle-version="1.12.1174" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: gov.noaa.nws.ncep.viz.ui.display Import-Package: com.raytheon.uf.common.topo, com.raytheon.uf.viz.core.rsc.legend, + com.raytheon.uf.viz.xy.timeseries.graph, + gov.noaa.nws.ncep.common.dataplugin.geomag.table, + gov.noaa.nws.ncep.common.dataplugin.geomag.util, gov.noaa.nws.ncep.gempak.parameters.colorbar, javax.measure.unit, javax.vecmath + diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.ui.display/plugin.xml index d7e2a98c70..e5838943cb 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/plugin.xml +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/plugin.xml @@ -21,6 +21,12 @@ id= "gov.noaa.nws.ncep.viz.ui.display.NTransDisplay" name="NTRANS Display"> + + + + * * @author ghull @@ -236,6 +236,9 @@ public abstract class AbstractNcPaneManager extends PaneManager implements return "gov.noaa.nws.ncep.viz.ui.display.NTransDisplay"; } else if (displayType == NcDisplayType.SOLAR_DISPLAY) { return "gov.noaa.nws.ncep.viz.ui.display.SolarDisplay"; + } else if (displayType == NcDisplayType.GRAPH_DISPLAY) { + return "gov.noaa.nws.ncep.viz.ui.display.GraphDisplay"; + } return "Unsupported displayType: " + displayType.toString(); } @@ -248,6 +251,9 @@ public abstract class AbstractNcPaneManager extends PaneManager implements return "gov.noaa.nws.ncep.viz.ui.display.NCNonMapRenderableDisplay"; } else if (displayType == NcDisplayType.SOLAR_DISPLAY) { return "gov.noaa.nws.ncep.viz.ui.display.NCNonMapRenderableDisplay"; + } else if (displayType == NcDisplayType.GRAPH_DISPLAY) { + return "gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesRenderableDisplay"; + } return "Unsupported displayTyep: " + displayType.toString(); } @@ -259,6 +265,8 @@ public abstract class AbstractNcPaneManager extends PaneManager implements return "gov.noaa.nws.ncep.viz.ui.display.NCNonMapDescriptor"; } else if (displayType == NcDisplayType.SOLAR_DISPLAY) { return "gov.noaa.nws.ncep.viz.ui.display.NCNonMapDescriptor"; + } else if (displayType == NcDisplayType.GRAPH_DISPLAY) { + return "gov.noaa.nws.ncep.viz.ui.display.NCTimeSeriesDescriptor"; } return "Unsupported displayTyep: " + displayType.toString(); } diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java index a306a179ea..bcb32b28a7 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCLegendHandler.java @@ -20,11 +20,11 @@ package gov.noaa.nws.ncep.viz.ui.display; import java.util.ArrayList; - import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Event; + import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.ResourcePair; @@ -36,10 +36,9 @@ import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; import com.raytheon.viz.ui.editor.AbstractEditor; import com.raytheon.viz.ui.input.EditableManager; - /** - * This handler is responsible for picking up mouse clicks and key press events on resources in - * the legend + * This handler is responsible for picking up mouse clicks and key press events + * on resources in the legend * *
  * 
@@ -58,9 +57,9 @@ import com.raytheon.viz.ui.input.EditableManager;
  * 10/19/2012   897         S. Gurung    Updated handleKeyUp() to not toggle PgenResource and added code to 
  * 										 refresh the editor after handling events.
  * 12/19/2012   960       G. Hull        use propertiesChanged() to toggle colorBar resources
- *                                        
- *                                                                                 
- *                                                  
+ * 
+ * 
+ * 
  * 
* * @author sgurung @@ -68,243 +67,256 @@ import com.raytheon.viz.ui.input.EditableManager; */ public class NCLegendHandler extends AbstractNCLegendInputHandler { - + /** * @param resource */ protected NCLegendHandler(NCLegendResource resource) { super(resource); } - + private ResourcePair mouseDownRsc = null; private static int currentRscIndex = 0; - - private boolean isShiftDown = false; - - private static boolean isFirstTime = true; + private boolean isShiftDown = false; - @Override + private static boolean isFirstTime = true; + + @Override public boolean handleMouseDown(int x, int y, int mouseButton) { - - if (mouseButton ==1 || mouseButton ==2) { - //IDisplayPaneContainer editor = getResourceContainer(); - //if (prefManager.handleClick(HIDE_RESOURCE_PREF, mouseButton)) { - AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); - if( editor != null && editor instanceof AbstractNcEditor ) { - IDisplayPane activePane = editor.getActiveDisplayPane(); - IRenderableDisplay display = editor.getActiveDisplayPane() - .getRenderableDisplay(); - mouseDownRsc = resource.checkLabelSpace(display.getDescriptor(), - activePane.getTarget(), x, y); - } - } - return false; + + if (mouseButton == 1 || mouseButton == 2) { + // IDisplayPaneContainer editor = getResourceContainer(); + // if (prefManager.handleClick(HIDE_RESOURCE_PREF, mouseButton)) { + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + if (editor != null && editor instanceof AbstractNcEditor) { + IDisplayPane activePane = editor.getActiveDisplayPane(); + IRenderableDisplay display = editor.getActiveDisplayPane() + .getRenderableDisplay(); + mouseDownRsc = resource.checkLabelSpace( + display.getDescriptor(), activePane.getTarget(), x, y); + } + } + return false; } - + @Override public boolean handleMouseUp(int x, int y, int mouseButton) { - - AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); - if (mouseButton ==1) { - if( editor != null && editor instanceof AbstractNcEditor ) { - IDisplayPane activePane = editor.getActiveDisplayPane(); - IRenderableDisplay display = editor.getActiveDisplayPane() - .getRenderableDisplay(); - ResourcePair rsc = resource.checkLabelSpace(display.getDescriptor(), - activePane.getTarget(), x, y); - if (rsc != null && rsc == mouseDownRsc) { - - mouseDownRsc = null; - toggleVisibility(rsc); - editor.refresh(); - - return true; - } - } - } - else if (mouseButton == 2 ){ - - if (mouseDownRsc != null && mouseDownRsc.getResource() - .hasCapability(EditableCapability.class)) { + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + if (mouseButton == 1) { + if (editor != null && editor instanceof AbstractNcEditor) { + IDisplayPane activePane = editor.getActiveDisplayPane(); + IRenderableDisplay display = editor.getActiveDisplayPane() + .getRenderableDisplay(); + ResourcePair rsc = resource.checkLabelSpace( + display.getDescriptor(), activePane.getTarget(), x, y); + + if (rsc != null && rsc == mouseDownRsc) { + + mouseDownRsc = null; + toggleVisibility(rsc); + editor.refresh(); + + return true; + } + } + } else if (mouseButton == 2) { + + if (mouseDownRsc != null + && mouseDownRsc.getResource().hasCapability( + EditableCapability.class)) { // check / make editable EditableManager.makeEditable( - mouseDownRsc.getResource(), + mouseDownRsc.getResource(), !mouseDownRsc.getResource() .getCapability(EditableCapability.class) .isEditable()); - mouseDownRsc = null; + mouseDownRsc = null; editor.refresh(); return true; } - } - return false; - + } + return false; + } - + @Override public boolean handleDoubleClick(int x, int y, int mouseButton) { return false; } + @Override - public boolean handleMouseDownMove(int x, int y, int mouseButton) { - return (mouseDownRsc != null); + public boolean handleMouseDownMove(int x, int y, int mouseButton) { + return (mouseDownRsc != null); } + public boolean handleMouseHover(int x, int y) { - return false; + return false; } - public boolean handleMouseMove(int x, int y) { - return false; + + public boolean handleMouseMove(int x, int y) { + return false; } - public boolean handleMouseWheel(Event event, int x, int y) { - return false; + + public boolean handleMouseWheel(Event event, int x, int y) { + return false; } - public boolean handleMouseExit(Event event) { - return false; + + public boolean handleMouseExit(Event event) { + return false; } - public boolean handleMouseEnter(Event event) { - return false; + + public boolean handleMouseEnter(Event event) { + return false; } @Override - public boolean handleKeyUp(int keyCode) { - - if ( keyCode != SWT.SHIFT && keyCode != SWT.ARROW_UP && keyCode != SWT.ARROW_DOWN ) { + public boolean handleKeyUp(int keyCode) { + + if (keyCode != SWT.SHIFT && keyCode != SWT.ARROW_UP + && keyCode != SWT.ARROW_DOWN) { return false; - } - - - if ( keyCode == SWT.SHIFT ) { - isShiftDown = true; - } - - - AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); - ResourceList theMainList = editor.getActiveDisplayPane().getDescriptor().getResourceList(); - - List subListOfResourcesToToggle = new ArrayList(0); - - if( isShiftDown ){ - /* - * Pressing the Shift key with either the up or the down arrow key makes - * all the non-system/non map layer resources visible. - */ - if (( keyCode == SWT.ARROW_UP || keyCode == SWT.ARROW_DOWN)){ - for ( ResourcePair resPair : theMainList){ - resPair.getProperties().setVisible(true); - } + } + + if (keyCode == SWT.SHIFT) { + isShiftDown = true; + } + + AbstractEditor editor = NcDisplayMngr.getActiveNatlCntrsEditor(); + ResourceList theMainList = editor.getActiveDisplayPane() + .getDescriptor().getResourceList(); + + List subListOfResourcesToToggle = new ArrayList( + 0); + + if (isShiftDown) { + /* + * Pressing the Shift key with either the up or the down arrow key + * makes all the non-system/non map layer resources visible. + */ + if ((keyCode == SWT.ARROW_UP || keyCode == SWT.ARROW_DOWN)) { + for (ResourcePair resPair : theMainList) { + resPair.getProperties().setVisible(true); + } } - }else{ + } else { /* - * Create 2 sublists.One for the colorbar resources and one for the - * requestable resources (non-system and non-map layer resources) + * Create 2 sublists.One for the colorbar resources and one for the + * requestable resources (non-system and non-map layer resources) * Set the visibility for all the resources in both lists to false. */ boolean allVisible = true; - - for ( ResourcePair resPair : theMainList){ - - if ( ! resPair.getProperties().isSystemResource() - && !resPair.getProperties().isMapLayer() - && resPair.getResource().getClass().getSimpleName().compareTo("PgenResource") != 0){ - subListOfResourcesToToggle.add(resPair); - allVisible = allVisible && resPair.getProperties().isVisible(); - resPair.getProperties().setVisible(false); - } - } - - if(subListOfResourcesToToggle.isEmpty()) - return false; - - if (allVisible) - isFirstTime = true; - - int listSize = subListOfResourcesToToggle.size(); - - if ( keyCode == SWT.ARROW_UP ){ - /*The navigation seems counter-intuitive. Yet this works since - *the elements displayed in the legend resource are listed from - *bottom-up - * - *The very first time either the up arrow is pressed - *the currentRscIndex gets initialized to the first element in the list - *Subsequently, if the up arrow is pressed, the index is incremented. - *If it points beyond the index of the last resource, - *then it gets reset to the index of the first resource - */ - if ( isFirstTime || isShiftDown) - currentRscIndex = 0; - else{ - currentRscIndex++; - if(currentRscIndex > (listSize - 1)) - currentRscIndex = 0; - } - - }else if (keyCode == SWT.ARROW_DOWN ){ + for (ResourcePair resPair : theMainList) { + + if (!resPair.getProperties().isSystemResource() + && !resPair.getProperties().isMapLayer() + && resPair.getResource().getClass().getSimpleName() + .compareTo("PgenResource") != 0) { + subListOfResourcesToToggle.add(resPair); + allVisible = allVisible + && resPair.getProperties().isVisible(); + resPair.getProperties().setVisible(false); + } + } + + if (subListOfResourcesToToggle.isEmpty()) + return false; + + if (allVisible) + isFirstTime = true; + + int listSize = subListOfResourcesToToggle.size(); + + if (keyCode == SWT.ARROW_UP) { /* - *The very first time either the down arrow is pressed - *the currentRscIndex gets initialized to the index of the last - *resource in the list - *Subsequently, if the down arrow is pressed, the index is decremented. - *If it points beyond the index of the first resource, - *then it gets set to the index of the last resource - */ - - if(isFirstTime || isShiftDown) - currentRscIndex = listSize - 1; - else{ - currentRscIndex--; - if( currentRscIndex < 0 ) - currentRscIndex = listSize - 1; - } - - } - - /*Make the resource visible*/ - ResourcePair rscToSetVisible = subListOfResourcesToToggle.get(currentRscIndex); - rscToSetVisible.getProperties().setVisible(true); - - // some resources may have an associated colorBar resource. This will - // be toggled when the resource's propertiesChanged() method is called. - // This is triggered by setVisible(); - - if ( isFirstTime && ( ( keyCode == SWT.ARROW_DOWN ) || ( keyCode == SWT.ARROW_UP ) )) - isFirstTime = false; - + * The navigation seems counter-intuitive. Yet this works since + * the elements displayed in the legend resource are listed from + * bottom-up + * + * The very first time either the up arrow is pressedthe + * currentRscIndex gets initialized to the first element in the + * listSubsequently, if the up arrow is pressed, the index is + * incremented.If it points beyond the index of the last + * resource,then it gets reset to the index of the first + * resource + */ + if (isFirstTime || isShiftDown) + currentRscIndex = 0; + else { + currentRscIndex++; + if (currentRscIndex > (listSize - 1)) + currentRscIndex = 0; + } + + } else if (keyCode == SWT.ARROW_DOWN) { + /* + * The very first time either the down arrow is pressedthe + * currentRscIndex gets initialized to the index of the last + * resource in the listSubsequently, if the down arrow is + * pressed, the index is decremented.If it points beyond the + * index of the first resource,then it gets set to the index of + * the last resource + */ + + if (isFirstTime || isShiftDown) + currentRscIndex = listSize - 1; + else { + currentRscIndex--; + if (currentRscIndex < 0) + currentRscIndex = listSize - 1; + } + + } + + /* Make the resource visible */ + ResourcePair rscToSetVisible = subListOfResourcesToToggle + .get(currentRscIndex); + rscToSetVisible.getProperties().setVisible(true); + + // some resources may have an associated colorBar resource. This + // will + // be toggled when the resource's propertiesChanged() method is + // called. + // This is triggered by setVisible(); + + if (isFirstTime + && ((keyCode == SWT.ARROW_DOWN) || (keyCode == SWT.ARROW_UP))) + isFirstTime = false; + } - - editor.refresh(); - - if( isShiftDown ){ - /* - *If the shift key was used to make all the resources - *visible again, the isFirstTime boolean is set to true - *So in effect the currentRscIndex is reset to either the first or the last - *non system/non map layer resource depending on which arrow key is - *subsequently pressed. - */ - isShiftDown = false; - isFirstTime = true; - } - return false; - } - - @Override - public boolean handleKeyDown(int keyCode) { - - if ( keyCode == SWT.SHIFT ) { - isShiftDown = true; - return false; - } - return false; - } - + + editor.refresh(); + + if (isShiftDown) { + /* + * If the shift key was used to make all the resourcesvisible again, + * the isFirstTime boolean is set to trueSo in effect the + * currentRscIndex is reset to either the first or the lastnon + * system/non map layer resource depending on which arrow key is + * subsequently pressed. + */ + isShiftDown = false; + isFirstTime = true; + } + return false; + } + + @Override + public boolean handleKeyDown(int keyCode) { + + if (keyCode == SWT.SHIFT) { + isShiftDown = true; + return false; + } + return false; + } + private void toggleVisibility(ResourcePair rp) { AbstractVizResource rsc = rp.getResource(); if (rsc != null) { @@ -333,47 +345,10 @@ public class NCLegendHandler extends AbstractNCLegendInputHandler { .toggle(rp); } } - + return; } } rp.getProperties().setVisible(!rp.getProperties().isVisible()); } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesDescriptor.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesDescriptor.java new file mode 100644 index 0000000000..d3314c4d19 --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesDescriptor.java @@ -0,0 +1,249 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.ui.display; + +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsDescriptor; + +import java.lang.reflect.Method; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.AbstractTimeMatcher; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.xy.graph.IGraph; +import com.raytheon.uf.viz.xy.graph.XyGraphDescriptor; + +/** + * Time Series descriptor, needed so loading bundles know what editor to load + * with this descriptor. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 04/21/2014   #1136      qzhou       Initial creation
+ * 05/21/2014   #1136      qzhou       Added override getCurrentFrame, getFrameCount
+ * 
+ * + * @author qzhou + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "NCTimeSeriesDescriptor") +@XmlRootElement +public class NCTimeSeriesDescriptor extends XyGraphDescriptor implements + INatlCntrsDescriptor { + + @XmlElement + private Boolean autoUpdate = false; + + @XmlElement + private Boolean suspendZoom = false; + + public NCTimeSeriesDescriptor() { + super(); + } + + public NCTimeSeriesDescriptor(PixelExtent pixelExtent) { + super(pixelExtent); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.xy.graph.XyGraphDescriptor#constructGraph() + */ + @Override + public IGraph constructGraph() { + return new NCTimeSeriesGraph(this); + } + + @Override + public Boolean isAutoUpdate() { + return autoUpdate; + } + + @Override + public void setAutoUpdate(Boolean autoUpdate) { + this.autoUpdate = autoUpdate; + if (getTimeMatcher() != null) { + // getTimeMatcher().setAutoUpdate( autoUpdate ); + } + } + + @Override + public Boolean getSuspendZoom() { + return suspendZoom; + } + + @Override + public void setSuspendZoom(Boolean suspendZoom) { + this.suspendZoom = suspendZoom; + } + + // would rather have add the descriptor to the timeMatcher here but this + // creates a cyclical dependency between display and resources. + @Override + public void setTimeMatcher(AbstractTimeMatcher timeMatcher) { + // if( this.timeMatcher != null ) { + // ((NCTimeMatcher)this.timeMatcher).removeDescriptor( this ); + // } + super.setTimeMatcher(timeMatcher); + // ((AbstractDescriptor) descriptor).getTimeMatchingMap().put( + // this, frameTimes.toArray( new DataTime[0] ) ); + + // timeMatcher.addDescriptor(); + } + + @Override + public void synchronizeTimeMatching(IDescriptor other) { + + } + + @Override + public void setFrameTimesForResource(AbstractVizResource rsc, + DataTime[] frameTimes) { + timeMatchingMap.put(rsc, frameTimes); + } + + @Override + public int getCurrentFrame() { + + return 0; + } + + @Override + public int getFrameCount() { + + return 1; + } + + // notify all of the resources in the resourceList that the timeline has + // changed so + // that they can update there frameDataMap. + // + // TODO : currently we can't reference classes in the resources project + // since this + // causes a cyclical dependency. This works around the problem by calling + // the update() + // method which is defined in AbstractResourceData (not a gov class) but a + // better solution + // would involve resolving the cyclical dependency issue and creating a + // method in + // AbstractNatlCntrsRequestableResourceData. + @Override + public void updateDataTimes(DataTime[] dataTimes) { + + setDataTimes(dataTimes); // this also resets bad frames. + + try { + // + for (ResourcePair rp : resourceList) { + if (rp.getResourceData() instanceof AbstractRequestableResourceData) { + + if (rp.getResource() != null) { + timeMatchingMap.put(rp.getResource(), dataTimes); + } + + // HACK ALERT : currently there is a cyclical dependency bug + // that prevents the display project from referencing the + // resources project. So we will use java reflection to get + // around this + // + Method[] mthds = rp.getResource().getClass().getMethods(); + + for (Method m : mthds) { + // System.out.println( m.getName() ); + if (m.getName().equals("updateTimeline")) { + if (m.getReturnType() == Boolean.class + && m.getParameterTypes().length == 0) { + m.invoke(rp.getResource()); + break; + } + } + } + } + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + /*** + * Provides the time of the frame, given the index of the frame in the + * DataTime array + * + *
+     * The time of the frame is displayed in the format: 
+     * Day yyMMdd/HHmm
+     * Example: Fri 100402/0505
+     * The time displayed is in GMT
+     * 
+ * + * @param currentIndex + * - The index of the frame whose time needs to be determined + * @return The valid time for the frame + */ + @Override + public String getValidTime(int currentIndex) { + Calendar cal; + String strTimeFrame = ""; + DataTime[] frameTimeArray = super.getFrames(); + + if (frameTimeArray != null) { + + cal = frameTimeArray[currentIndex].getValidTime(); + strTimeFrame = new String(getFrameDateFormat() + .format(cal.getTime())); + + } + + return strTimeFrame.toUpperCase(); + } + + public static SimpleDateFormat getFrameDateFormat() { + FRAME_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT")); + return FRAME_DATE_FORMAT; + } + + // only 1 instance + @Override + public void addFrameChangedListener(IFrameChangedListener listener) { + synchronized (listener) { + if (!listeners.contains(listener)) { + super.addFrameChangedListener(listener); + } + } + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesGraph.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesGraph.java new file mode 100644 index 0000000000..c069c65cec --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesGraph.java @@ -0,0 +1,219 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package gov.noaa.nws.ncep.viz.ui.display; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.xy.graph.AbstractGraph; +import com.raytheon.uf.viz.xy.graph.XyGraphDescriptor; +import com.raytheon.uf.viz.xy.graph.axis.GraphAxis; +import com.raytheon.uf.viz.xy.graph.axis.IAxis; +import com.raytheon.uf.viz.xy.graph.axis.LinearAxisPlacer; +import com.raytheon.uf.viz.xy.graph.labeling.IGraphLabel; +import com.raytheon.uf.viz.xy.map.rsc.IGraphableResource; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * The NC Time Series graph + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 4/18/2014               qzhou       Similar to TimeSeriesGraph
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + */ + +public class NCTimeSeriesGraph extends AbstractGraph { + + protected static final DecimalFormat df = new DecimalFormat("#.0###"); + + /** The x labels */ + protected List> xLabels; + + public NCTimeSeriesGraph(XyGraphDescriptor descriptor) { + super(descriptor); + xLabels = new ArrayList>(); + } + + @Override + protected void createAxes() { + // Create the Axis if they do not exist + if (xAxes.length == 0) { + xAxes = new IAxis[11]; + for (int i = 0; i < xAxes.length; ++i) { + xAxes[i] = new GraphAxis(); + xAxes[i].setLineStyle(LineStyle.DASHED); + xAxes[i].setDrawAxis(true); + } + } + + // Update the values + double inc = xAxisPlacer.getDataWidth() / 10; + double val = Math.ceil(xAxisPlacer.getMinDataValue() / inc) * inc; + + for (int i = 0; i < xAxes.length; i++) { + xAxes[i].setDiscreteValue(val + inc * i); + } + + // Place them + double minX = graphExtent.getMinX(); + double maxX = graphExtent.getMaxX(); + double maxY = graphExtent.getMaxY(); + + xAxisPlacer.setPixelWidth(graphExtent.getHeight()); + yAxisPlacer.setPixelWidth(graphExtent.getWidth()); + + // Place the data axes + double[] offsets = xAxisPlacer.placeAxes(xAxes); + + for (int i = 0; i < offsets.length; ++i) { + double offset = offsets[i]; + xAxes[i].setStartLoc(new Coordinate(minX, maxY - offset, 0)); + xAxes[i].setEndLoc(new Coordinate(maxX, maxY - offset, 0)); + } + } + + @Override + protected boolean canHandleResoruce(IGraphableResource rsc) { + // TODO Auto-generated method stub + return false; + } + + @Override + protected void paintTitles(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + } + + @Override + protected void paintUnits(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + + RGB colorToUse = null; + List strings = new ArrayList(); + for (IGraphableResource grsc : graphResource) { + + for (int i = 0; i < xAxes.length; i++) { + Coordinate[] coords = xAxes[i].getCoordinates(); + if (coords[0].y < graphExtent.getMinY()) { + continue; + } + + DrawableString parameters = new DrawableString("", colorToUse); + parameters.font = unitsFont; + parameters.textStyle = TextStyle.DROP_SHADOW; + parameters.horizontalAlignment = HorizontalAlignment.RIGHT; + parameters.magnification = this.currentMagnification; + + String value = df.format(xAxes[i].getDiscreteValue()); + if (i == 0) { + parameters.verticallAlignment = VerticalAlignment.BOTTOM; + } else { + parameters.verticallAlignment = VerticalAlignment.MIDDLE; + } + parameters.setText(value, colorToUse); + parameters + .setCoordinates(coords[0].x, coords[0].y, coords[0].z); + strings.add(parameters); + } + } + target.drawStrings(strings); + + paintDataTimeUnits(target, paintProps, xLabels); + } + + @Override + public void constructVirtualExtent() { // IGraphicsTarget target) { + + // TODO: Loop through resources and create extent then call + // updateVirtualExtent + double[] minMaxY = new double[2]; + xLabels.clear(); + ArrayList> yLabels = new ArrayList>(); + getRangeData(xLabels, yLabels); + + double minX = 0; + double maxX = 0; + minMaxY[0] = 0; + minMaxY[1] = 0; + + if (yLabels.size() > 0) { + minMaxY[0] = yLabels.get(0).getDiscreteValue(); + minMaxY[1] = yLabels.get(yLabels.size() - 1).getDiscreteValue(); + } + if (xLabels.size() > 0) { + minX = xLabels.get(0).getDiscreteValue(); + maxX = xLabels.get(xLabels.size() - 1).getDiscreteValue(); + } + // normalizeAxis now takes into accout data that will never be + // negative like wind speed. + normalizeAxis(minMaxY); + + xAxisPlacer = new LinearAxisPlacer(graphExtent.getHeight(), minMaxY[0], + minMaxY[1]); + yAxisPlacer = new LinearAxisPlacer(graphExtent.getWidth(), minX, maxX); + + updateVirtualExtent(); + + newResources = false; + + } + + @Override + public void zoom(int index, Coordinate gridCoord) { + yAxisPlacer.zoom(gridCoord.x - graphExtent.getMinX(), index); + xAxisPlacer.zoom(graphExtent.getMaxY() - gridCoord.y, index); + double inc = xAxisPlacer.getDataWidth() / 10; + double newMin = (int) (xAxisPlacer.getMinDataValue() / inc) * inc; + xAxisPlacer.pan(xAxisPlacer.getPixelLoc(newMin)); + updateVirtualExtent(); + } + + @Override + public void pan(double xDist, double yDist, boolean panning) { + yAxisPlacer.pan(xDist); + xAxisPlacer.pan(-yDist); + if (!panning) { + double inc = xAxisPlacer.getDataWidth() / 10; + double newMin = Math.round(xAxisPlacer.getMinDataValue() / inc) + * inc; + xAxisPlacer.pan(xAxisPlacer.getPixelLoc(newMin)); + } + updateVirtualExtent(); + } +} diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java new file mode 100644 index 0000000000..50d9ebfefe --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.viz.ui.display/src/gov/noaa/nws/ncep/viz/ui/display/NCTimeSeriesRenderableDisplay.java @@ -0,0 +1,341 @@ +package gov.noaa.nws.ncep.viz.ui.display; + +import gov.noaa.nws.ncep.viz.common.area.PredefinedArea; +import gov.noaa.nws.ncep.viz.common.area.PredefinedAreaFactory; +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsPaneManager; +import gov.noaa.nws.ncep.viz.common.display.INatlCntrsRenderableDisplay; +import gov.noaa.nws.ncep.viz.common.display.INcPaneID; +import gov.noaa.nws.ncep.viz.common.display.NcDisplayName.NcPaneName; +import gov.noaa.nws.ncep.viz.common.display.NcDisplayType; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.geotools.coverage.grid.GeneralGridEnvelope; +import org.geotools.coverage.grid.GeneralGridGeometry; +import org.geotools.coverage.grid.GridGeometry2D; +import org.geotools.geometry.GeneralEnvelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource.ResourceStatus; +import com.raytheon.uf.viz.core.rsc.GenericResourceData; +import com.raytheon.uf.viz.core.rsc.IResourceGroup; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.ResourceList.AddListener; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability; +import com.raytheon.uf.viz.xy.graph.AbstractXyRenderableDisplay; +import com.raytheon.uf.viz.xy.map.rsc.GraphResource; +import com.raytheon.uf.viz.xy.map.rsc.GraphResourceData; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * MapRenderableDisplay for NatlCntrs + * + *
+ * 
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 04/21/2014   #1136      qzhou       Initial creation
+ * 
+ * 
+ * + * @author qzhou + * @version 1.0 + * @param + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "NCTimeSeriesRenderableDisplay") +@XmlRootElement +public class NCTimeSeriesRenderableDisplay extends AbstractXyRenderableDisplay + implements AddListener, INatlCntrsRenderableDisplay, + ISerializableObject { + + @XmlElement + private NcPaneID paneId; + + // either the RBD or the Display's paneManager + private INatlCntrsPaneManager paneContainer; + + // the initial area that the display is set to. This is used for the unzoom. + // after the display is loaded the user may pan/zoom in which case the + // current + // area(gridGeometry,zoom,mapcenter) will be different than the initial + // area. + // + // @XmlElement + private PredefinedArea initialArea; + + public static final GenericResourceData legendRscData = new GenericResourceData( + NCLegendResource.class); + + public static final GenericResourceData selectedRscData = new GenericResourceData( + NcSelectedPaneResource.class); + + public NCTimeSeriesRenderableDisplay() { + this(new NcPaneID(), new PixelExtent(0, 1000, 0, 1000)); + } + + public NCTimeSeriesRenderableDisplay(NcPaneID pid, PixelExtent pe) { + super(pe, new NCTimeSeriesDescriptor()); + this.setPaneId(pid); + } + + @Override + public double[] getMapCenter() { + return getExtent().getCenter(); + } + + // this shouldn't be called from NCP but override as a sanity check since + // AbstractXYRenderableDisplay's setTabTitle() calls getEditor which assumes + // an XyEditor + public void setTabTitle(String tabTitle) { + // tabTitle = tabTitle; + // if (getEditor() != null) { + // getEditor().setTabTitle(tabTitle); + // } + } + + @Override + public void dispose() { + if (this.descriptor != null) {// && editorInstanceNum <= 1) { + descriptor.getResourceList().clear(); + this.descriptor.getResourceList().removePostAddListener( + this.listener); + this.descriptor.getResourceList().removePostRemoveListener( + this.listener); + } + } + + @Override + public NcPaneName getPaneName() { + if (getPaneManager().getPaneLayout().getNumberOfPanes() == 1) { + return new NcPaneName(getPaneManager().getDisplayName()); + + } else { + return new NcPaneName(getPaneManager().getDisplayName(), + getPaneId()); + } + } + + @Override + public NcPaneID getPaneId() { + if (paneId == null) { + paneId = new NcPaneID(); + } + return paneId; + } + + @Override + public void setPaneId(INcPaneID pid) { + paneId = (NcPaneID) pid; + } + + // TODO? if null then set to the descriptors gridGeom?? + @Override + public NCTimeSeriesDescriptor getDescriptor() { + if (super.getDescriptor() instanceof NCTimeSeriesDescriptor) { + return (NCTimeSeriesDescriptor) super.getDescriptor(); + } else { + super.getDescriptor(); + } + + return null; + } + + @Override + public void setExtent(IExtent pe) { + super.setExtent(pe); + } + + // + @Override + public PredefinedArea getInitialArea() { + if (initialArea == null) { + try { + initialArea = PredefinedAreaFactory + .getDefaultPredefinedAreaForDisplayType(NcDisplayType.GRAPH_DISPLAY); + } catch (VizException e) { + } + + } + return initialArea; + } + + private GeneralGridGeometry createGridGeometry(IExtent extent, + CoordinateReferenceSystem crs) { + // copied from AbstractDescriptor since it was protected + GeneralEnvelope envelope = new GeneralEnvelope(2); + envelope.setRange(0, extent.getMinX(), extent.getMaxX()); + envelope.setRange(1, extent.getMinY(), extent.getMaxY()); + envelope.setCoordinateReferenceSystem(crs); + return new GridGeometry2D( + new GeneralGridEnvelope(new int[] { 0, 0 }, new int[] { + (int) extent.getWidth(), (int) extent.getHeight() }, + false), envelope); + } + + @Override + public double getZoomLevel() { + return 1.0; + } + + @Override + public void setInitialArea(PredefinedArea area) { + initialArea = area; + + try { + // setPredefinedArea( initialArea ); + getDescriptor().setGridGeometry(area.getGridGeometry()); + + // if( initialArea.getMapCenter() == null ) { + // initialArea.setMapCenter( getMapCenter() ); + // } + + } catch (VizException e) { + System.out + .println("Error setting initial area of renderable display:" + + e.getMessage()); + } + // if this is actually called/needed then check that the crs is 2d + // Cartesian + // and set the extents. + + // System.out.println("setInitialArea not implemented for non-map display"); + } + + @Override + protected void customizeResourceList(ResourceList resourceList) { + // resourceList. // check if already in the list??? + super.customizeResourceList(resourceList); + + // Add time series graph resource + GraphResourceData grd = new GraphResourceData("Time series"); + GraphResource gr = null; + LoadProperties lprops = new LoadProperties(); + ResourceProperties rprops = new ResourceProperties(); + rprops.setMapLayer(true); + try { + gr = grd.construct(lprops, getDescriptor()); + grd.setOverlayMode(GraphResourceData.OverlayMode.OVERLAY); + ResourcePair rp = new ResourcePair(); + rp.setResourceData(grd); + rp.setResource(gr); + rp.setProperties(rprops); + rp.setLoadProperties(lprops); + resourceList.add(rp); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error constructing time series Graph", e); + } + + resourceList.add(ResourcePair + .constructSystemResourcePair(legendRscData)); + resourceList.add(ResourcePair + .constructSystemResourcePair(selectedRscData)); + resourceList.addPostAddListener(this); + + } + + @Override + public void notifyAdd(ResourcePair rp) throws VizException { + + // TODO : any checks on the type of resource here. + AbstractNcPaneManager pm = NcEditorUtil + .getNcPaneManager((AbstractEditor) container); + if (pm != null) { + pm.setDisplayAvailable(false); + } + } + + protected boolean shouldDisplay(ResourcePair pair, int displayWidth) { + AbstractVizResource rsc = pair.getResource(); + ResourceProperties properties = pair.getProperties(); + + if (rsc == null) { + return false; + } + + ResourceStatus status = rsc.getStatus(); + + if (status == ResourceStatus.DISPOSED) { + return false; + } + + boolean doNotDrawBecauseOfBlinking = false; + if (properties.isBlinking()) { + if (!rsc.hasCapability(ColorMapCapability.class)) { + // Not a colormapped image... + doNotDrawBecauseOfBlinking = !getCurrentBlinkState(); + } else { + ColorMapParameters params = rsc.getCapability( + ColorMapCapability.class).getColorMapParameters(); + params.setUseMask(!getCurrentBlinkState()); + // notify the resource it is blinking. + rsc.issueRefresh(); + } + } + + if (!doNotDrawBecauseOfBlinking) { + if (pair.getResource() instanceof IResourceGroup) { + for (ResourcePair rp : ((IResourceGroup) pair.getResource()) + .getResourceList()) { + doNotDrawBecauseOfBlinking &= shouldDisplay(rp, + displayWidth); + } + } + } + + boolean drawBecauseItsNew = status == ResourceStatus.NEW; + + if (!drawBecauseItsNew) { + if (pair.getResource() instanceof IResourceGroup) { + for (ResourcePair rp : ((IResourceGroup) pair.getResource()) + .getResourceList()) { + if (rp.getResource() != null) { + drawBecauseItsNew |= rp.getResource().getStatus() == ResourceStatus.NEW; + } + } + } + } + + return (drawBecauseItsNew || properties.isDisplayable(displayWidth)) + && !doNotDrawBecauseOfBlinking; + } + + @Override + public void setPaneManager(INatlCntrsPaneManager pm) { + paneContainer = pm; + } + + @Override + public void setContainer(IDisplayPaneContainer container) { + super.setContainer(container); + + if (container instanceof AbstractEditor) { + INatlCntrsPaneManager pm = NcEditorUtil + .getNcPaneManager((AbstractEditor) container); + setPaneManager(pm); + } + } + + @Override + public INatlCntrsPaneManager getPaneManager() { + return paneContainer; + } + +} diff --git a/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml b/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml index 42137ffc68..4fbf382725 100644 --- a/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml +++ b/ncep/gov.noaa.nws.ncep.viz.ui.perspectives/plugin.xml @@ -618,7 +618,19 @@ - + + + + + + NC * 09/27/2009 169 G. Hull require NCMapEditor - * + * 07/07/2014 R4079 Q. Zhou Add timeseries view * * - * @author + * @author * @version 1 */ public class NCPerspective implements IPerspectiveFactory { /** ID_PERSPECTIVE field */ public static final String ID_PERSPECTIVE = "gov.noaa.nws.ncep.viz.ui.NCPerspective"; //$NON-NLS-1$ - - + /* * (non-Javadoc) * - * @see org.eclipse.ui.IPerspectiveFactory#createInitialLayout(org.eclipse.ui.IPageLayout) + * @see + * org.eclipse.ui.IPerspectiveFactory#createInitialLayout(org.eclipse.ui + * .IPageLayout) */ public void createInitialLayout(IPageLayout layout) { - - String refId = layout.getEditorArea(); + + String refId = layout.getEditorArea(); // Get the editor area. - - long t0 = System.currentTimeMillis(); + + long t0 = System.currentTimeMillis(); layout.getEditorArea(); -// long t1 = System.currentTimeMillis(); -// System.out.println("Time to get Editor Area: " + (t1-t0) + " ms"); - + // long t1 = System.currentTimeMillis(); + // System.out.println("Time to get Editor Area: " + (t1-t0) + " ms"); + layout.setFixed(false); -// long t2 = System.currentTimeMillis(); -// System.out.println("Time to set Fixed: " + (t2-t1) + " ms"); - + // long t2 = System.currentTimeMillis(); + // System.out.println("Time to set Fixed: " + (t2-t1) + " ms"); + layout.addPlaceholder(PgenUtil.VIEW_ID, IPageLayout.LEFT, 0.15f, refId); -// long t3 = System.currentTimeMillis(); -// System.out.println("Time to add Placeholder: " + (t3-t2) + " ms"); - - layout.addPlaceholder("gov.noaa.nws.ncep.ui.nsharp", IPageLayout.LEFT, 0.15f, refId); -// long t4 = System.currentTimeMillis(); -// System.out.println("Time to add Placeholder for NSHARP: " + (t4-t3) + " ms"); - + // long t3 = System.currentTimeMillis(); + // System.out.println("Time to add Placeholder: " + (t3-t2) + " ms"); + + layout.addPlaceholder("gov.noaa.nws.ncep.ui.nsharp", IPageLayout.LEFT, + 0.15f, refId); + // long t4 = System.currentTimeMillis(); + // System.out.println("Time to add Placeholder for NSHARP: " + (t4-t3) + // + " ms"); + + layout.addPlaceholder( + "gov.noaa.nws.ncep.viz.rsc.timeseries.view.SamplingView", + IPageLayout.LEFT, 0.25f, refId); + layout.addPlaceholder( + "gov.noaa.nws.ncep.viz.rsc.timeseries.view.KTableView", + IPageLayout.BOTTOM, 0.75f, refId); + layout.addActionSet("gov.noaa.nws.ncep.viz.ui.personalities.NCActionSet"); + long t5 = System.currentTimeMillis(); -// System.out.println("Time to add Action set: " + (t5-t4) + " ms"); - System.out.println("Time to Create NCP perspective layout: " + (t5-t0) + " ms"); + // System.out.println("Time to add Action set: " + (t5-t4) + " ms"); + System.out.println("Time to Create NCP perspective layout: " + + (t5 - t0) + " ms"); } /* * (non-Javadoc) * - * @see com.raytheon.viz.ui.IVizPerspectiveFactory#getEditorContributions(com.raytheon.viz.core.IDisplayPaneContainer, - * com.raytheon.viz.core.IDisplayPane) + * @see + * com.raytheon.viz.ui.IVizPerspectiveFactory#getEditorContributions(com + * .raytheon.viz.core.IDisplayPaneContainer, + * com.raytheon.viz.core.IDisplayPane) */ // [TO10 HOLD] @Override - // [TO10 HOLD] Following is no longer in IVizPerspectiveFactory as of TO10 -- + // [TO10 HOLD] Following is no longer in IVizPerspectiveFactory as of TO10 + // -- // [TO10 HOLD] need to understand the implications of this public AbstractRightClickAction[] getEditorContributions( IDisplayPaneContainer container, IDisplayPane pane) { - // zoomMenuAction.setContainer(container); - // return new AbstractRightClickAction[] { zoomMenuAction }; - return null; + // zoomMenuAction.setContainer(container); + // return new AbstractRightClickAction[] { zoomMenuAction }; + return null; } }