001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.tools.csmart.recipe;
027:
028: import org.cougaar.tools.csmart.core.db.PDbBase;
029: import org.cougaar.tools.csmart.core.property.ConfigurableComponent;
030: import org.cougaar.tools.csmart.core.property.ConfigurableComponentProperty;
031: import org.cougaar.tools.csmart.core.property.range.StringRange;
032: import org.cougaar.tools.csmart.ui.viewer.CSMART;
033: import org.cougaar.util.ConfigFinder;
034: import org.cougaar.util.DBProperties;
035: import org.cougaar.util.log.Logger;
036:
037: import java.io.File;
038: import java.io.IOException;
039: import java.util.Iterator;
040: import java.util.Set;
041: import java.util.TreeSet;
042:
043: /**
044: * Extends ConfigurableComponentProperty in order to override the
045: * getAllowedValues method with values obtained from the set of
046: * available queries.
047: **/
048: public class RecipeQueryProperty extends ConfigurableComponentProperty {
049: public RecipeQueryProperty(ConfigurableComponent c, String name,
050: Object value) {
051: super (c, name, value);
052: setPropertyClass(StringRange.class);
053: }
054:
055: public Set getAllowedValues() {
056: return getAvailableQueries();
057: }
058:
059: // Cached list of available recipe queries
060: private static Set availQueries = null;
061:
062: // When was the recipeQueries.q file last modified
063: private static long rQFileLastMod = 0l;
064:
065: // Get the recipe queries available, updating the local cache
066: private static Set getAvailableQueries() {
067: Logger log = CSMART
068: .createLogger("org.cougaar.tools.csmart.recipe.RecipeQueryProperty");
069:
070: // Get the last modified date of the recipeQueries file.
071: // If it's the same now as it was before, dont re-read
072: File rqfile = ConfigFinder.getInstance("csmart").locateFile(
073: RecipeComponent.RECIPE_QUERY_FILE);
074: long newMod = 0l;
075: if (rqfile != null) {
076: try {
077: newMod = rqfile.lastModified();
078: } catch (SecurityException se) {
079: }
080: }
081:
082: // If we have never read the available queries, or the recipeQueries.q file was modified,
083: // must re-collect the available queries
084: if (availQueries == null || newMod != rQFileLastMod) {
085: availQueries = new TreeSet(); // keep queries sorted by name
086: DBProperties dbp = null;
087:
088: // First grab the queries from PopulateDb.q
089: // Note that this is the cached DBProperties - which may already
090: // have the contents of recipeQueries.q in it
091: try {
092: // If have read the file before but still got indication of a change,
093: // then re-read the query file to throw out any query name changes
094: if (rQFileLastMod != 0l) {
095: if (log.isDebugEnabled()) {
096: log.debug("Re-reading query files.");
097: }
098: dbp = DBProperties.reReadQueryFile(
099: PDbBase.QUERY_FILE, "csmart").unlock();
100: } else
101: dbp = DBProperties.readQueryFile(
102: PDbBase.QUERY_FILE, "csmart").unlock();
103: } catch (IOException ioe) {
104: if (log.isDebugEnabled()) {
105: log.debug("Couldn't read " + PDbBase.QUERY_FILE);
106: }
107: }
108:
109: rQFileLastMod = 0l;
110:
111: // Add in the contents of recipeQueries.q - possibly just over-writing
112: // the values previously added
113: try {
114: // Add to the basic PopDb.q the queries in recipeQueries.q
115: dbp.addQueryFile(RecipeComponent.RECIPE_QUERY_FILE,
116: "csmart");
117: rQFileLastMod = newMod;
118: } catch (IOException e) {
119: if (log.isDebugEnabled()) {
120: log.debug("No " + RecipeComponent.RECIPE_QUERY_FILE
121: + " file found.");
122: }
123: }
124:
125: // Now collect the query names from the combo .q file
126: for (Iterator i = dbp.keySet().iterator(); i.hasNext();) {
127: String s = i.next().toString();
128: if (s.startsWith("recipeQuery")) {
129: StringRange sr = new StringRange(s);
130: // Since on save only the last query of a given name is available,
131: // only list queries with a duplicate name once
132: if (!availQueries.contains(sr))
133: availQueries.add(sr);
134: }
135: } // loop over query names
136: } // end of block to (re-)read the queries
137:
138: return availQueries;
139: }
140: }
|