001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: //Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: //This program is free software; you can redistribute it and/or
006: //modify it under the terms of the GNU General Public License version 2
007: //as published by the Free Software Foundation;
008: //
009: //This program is distributed in the hope that it will be useful,
010: //but WITHOUT ANY WARRANTY; without even the implied warranty of
011: //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: //GNU General Public License for more details.
013: //
014: //You should have received a copy of the GNU General Public License
015: //along with this program; if not, write to the Free Software
016: //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: //For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020:
021: package com.salmonllc.sitemap;
022:
023: import java.io.File;
024: import java.io.FileInputStream;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.io.StringReader;
028: import java.util.Hashtable;
029:
030: import javax.xml.parsers.SAXParser;
031: import javax.xml.parsers.SAXParserFactory;
032:
033: import org.xml.sax.Attributes;
034: import org.xml.sax.InputSource;
035: import org.xml.sax.SAXException;
036:
037: import com.salmonllc.properties.Props;
038: import com.salmonllc.util.TwoObjectContainer;
039:
040: /**
041: * Internal class used to parse the sitemap xml file
042: *
043: */
044: class SiteMapParser extends org.xml.sax.helpers.DefaultHandler {
045:
046: private static String DTD = "<?xml encoding=\"US-ASCII\"?> <!ELEMENT sitemap (entry)+> <!ELEMENT entry (name,uri,useForward?, secure?, popupFeatures?, action?,context?)> <!ELEMENT name (#PCDATA)> <!ELEMENT uri (#PCDATA)> <!ELEMENT secure (#PCDATA)> <!ELEMENT useForward (#PCDATA)> <!ELEMENT popupFeatures (#PCDATA)> <!ELEMENT action (actionName,actionEntry)><!ELEMENT actionName (#PCDATA)><!ELEMENT actionEntry (#PCDATA)> <!ELEMENT context (#PCDATA)> ";
047:
048: private static Hashtable _loadedMaps = new Hashtable();
049: private SiteMap _map;
050: private String _currentChars;
051: private String _name;
052: private String _uri;
053: private String _context;
054: private boolean _secure;
055: private boolean _forward;
056: private String _popupFeatures;
057: private String _actionName;
058: private String _actionEntry;
059:
060: private SiteMapParser(String appName, InputStream in) {
061: try {
062: _map = new SiteMap(appName);
063: SAXParserFactory factory = SAXParserFactory.newInstance();
064: SAXParser parser = factory.newSAXParser();
065: parser.parse(new InputSource(in), this );
066: } catch (Exception e) {
067: e.printStackTrace(System.err);
068: }
069: }
070:
071: private SiteMap getMap() {
072: return _map;
073: }
074:
075: /**
076: * Part of the XML Parser implementation. Do not call directly.
077: */
078: public InputSource resolveEntity(String publicId, String systemId)
079: throws SAXException {
080: return new InputSource(new StringReader(DTD));
081: }
082:
083: /* (non-Javadoc)
084: * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
085: */
086: public void startElement(String uri, String localName,
087: String qName, Attributes attributes) throws SAXException {
088: _currentChars = "";
089: }
090:
091: /**
092: * Part of the XML Parser implementation. Do not call directly.
093: */
094: public void characters(char[] ch, int start, int length)
095: throws SAXException {
096: _currentChars += new String(ch, start, length);
097: }
098:
099: /**
100: * Part of the XML Parser implementation. Do not call directly.
101: */
102: public void endElement(String uri, String localName, String name) {
103: if (name.equals("entry")) {
104: _map.putEntry(_name, _uri, _popupFeatures, _forward,
105: _secure, _context);
106: _name = null;
107: _context = null;
108: _uri = null;
109: _secure = false;
110: _forward = false;
111: _popupFeatures = null;
112: _actionName = null;
113: _actionEntry = null;
114: } else if (name.equals("action")) {
115: _map.addActionEntry(_name, _actionName, _actionEntry);
116: _actionName = null;
117: _actionEntry = null;
118: } else if (name.equals("name"))
119: _name = _currentChars;
120: else if (name.equals("uri"))
121: _uri = _currentChars;
122: else if (name.equals("popupFeatures"))
123: _popupFeatures = _currentChars;
124: else if (name.equalsIgnoreCase("useForward"))
125: _forward = _currentChars.equalsIgnoreCase("true");
126: else if (name.equalsIgnoreCase("secure"))
127: _secure = _currentChars.equalsIgnoreCase("true");
128: else if (name.equals("actionName"))
129: _actionName = _currentChars;
130: else if (name.equals("actionEntry"))
131: _actionEntry = _currentChars;
132: else if (name.equals("context"))
133: _context = _currentChars;
134:
135: }
136:
137: /**
138: * Gets the sitemap for the specified applicaion
139: * @throws IOException
140: */
141: public static SiteMap getSiteMap(String appName) throws IOException {
142: String filePath = Props.getPropsPath();
143: if (!filePath.endsWith(File.separator))
144: filePath += File.separator;
145: String fileName = filePath + appName + ".map";
146: File f = new File(fileName);
147: if (!f.exists()) {
148: fileName = filePath + "System.map";
149: f = new File(fileName);
150: if (!f.exists())
151: return new SiteMap(appName);
152: }
153:
154: long lastMod = f.lastModified();
155:
156: TwoObjectContainer cont = (TwoObjectContainer) _loadedMaps
157: .get(appName);
158: if (cont != null
159: && lastMod == ((Long) cont.getObject1()).longValue())
160: return (SiteMap) cont.getObject2();
161:
162: FileInputStream in = new FileInputStream(f);
163: SiteMapParser ps = new SiteMapParser(appName, in);
164: in.close();
165: cont = new TwoObjectContainer(new Long(lastMod), ps.getMap());
166: _loadedMaps.put(appName, cont);
167: return ps.getMap();
168: }
169:
170: }
|