001: /*
002: * Copyright 2001-2007 Hippo (www.hippo.nl)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package nl.hippo.cms.spellchecking.generation;
017:
018: import java.util.HashMap;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022: import java.util.Vector;
023:
024: import java.io.BufferedReader;
025: import java.io.IOException;
026: import java.io.StringReader;
027:
028: import org.apache.avalon.framework.parameters.Parameters;
029: import org.apache.cocoon.ProcessingException;
030: import org.apache.cocoon.environment.SourceResolver;
031: import org.apache.cocoon.generation.ServiceableGenerator;
032: import org.apache.cocoon.xml.XMLConsumer;
033:
034: import org.xml.sax.Attributes;
035: import org.xml.sax.SAXException;
036: import org.xml.sax.helpers.AttributesImpl;
037: import org.xml.sax.helpers.DefaultHandler;
038:
039: import nl.hippo.cms.spellchecking.*;
040:
041: public class AspellGenerator extends ServiceableGenerator {
042: private String ASPELL_LOCATION = "";
043: private String ASPELL_DICTIONARY = "";
044: private String ASPELL_CONTENT = "";
045: private String NEW_ASPELL_CONTENT = "";
046:
047: AttributesImpl emptyAttr = new AttributesImpl();
048:
049: public void setup(SourceResolver resolver, Map objectModel,
050: String src, Parameters par) throws ProcessingException,
051: SAXException, IOException {
052: super .setup(resolver, objectModel, src, par);
053: ASPELL_LOCATION = par.getParameter("location", "");
054: ASPELL_DICTIONARY = par.getParameter("dictionary", "");
055: ASPELL_CONTENT = par.getParameter("content", "");
056: }
057:
058: public void generate() throws SAXException {
059:
060: if (this .getLogger().isDebugEnabled()) {
061: this .getLogger().debug(
062: "content comming from htmlarea: " + ASPELL_CONTENT);
063: }
064:
065: AttributesImpl attrs = new AttributesImpl();
066: attrs.addAttribute("", "dictionary", "dictionary", "",
067: ASPELL_DICTIONARY);
068:
069: contentHandler.startDocument();
070: contentHandler.startElement("", "result", "result", attrs);
071: generateAspellResult();
072: //TODO: JR fix this function
073: generateContentResult();
074: contentHandler.endElement("", "result", "result");
075: contentHandler.endDocument();
076: NEW_ASPELL_CONTENT = "";
077: if (this .getLogger().isDebugEnabled()) {
078: this .getLogger().debug(
079: "Finished generating xml result from spellchecker");
080: }
081: }
082:
083: public void generateContentResult() {
084: AttributesImpl attrs = new AttributesImpl();
085: try {
086: contentHandler.startElement("", "TMPCONTENT", "TMPCONTENT",
087: attrs);
088: contentHandler.characters(NEW_ASPELL_CONTENT.toCharArray(),
089: 0, NEW_ASPELL_CONTENT.length());
090: contentHandler.endElement("", "TMPCONTENT", "TMPCONTENT");
091: } catch (Exception e) {
092: if (this .getLogger().isDebugEnabled()) {
093: this .getLogger().debug(
094: "Error occured while adding content");
095: }
096: }
097: /*
098: try
099: {
100: AttributesImpl attrs = new AttributesImpl();
101: String ct= "<content>" + NEW_ASPELL_CONTENT + "</content>";
102: System.out.println("ct: " + ct);
103: ByteArrayInputStream bais = new ByteArrayInputStream(ct.getBytes());
104:
105: if (bais != null && bais.available() > 0){
106: SAXParser parser = null;
107: try {
108: parser = (SAXParser) manager.lookup(SAXParser.ROLE);
109: //[JR] super.xmlConsumer will send this to the next component in the sitemap.
110: parser.parse(new InputSource(bais), new ForwardHandler(super.xmlConsumer));
111: } catch (SourceException e) {
112: throw SourceUtil.handle(e);
113: } catch (ServiceException e) {
114: throw new ProcessingException("Exception during parsing source.", e);
115: } finally {
116: manager.release(parser);
117: }
118: } else {
119: throw new ProcessingException("This does not work.");
120: }
121: }
122: catch(Exception e)
123: {
124:
125: }*/
126: }
127:
128: public void generateAspellResult() {
129:
130: String inputLine;
131: boolean isValid = false;
132:
133: AttributesImpl emptyAttrs = new AttributesImpl();
134: AspellWrapper aw = new AspellWrapper();
135: aw.setASpellLocation(ASPELL_LOCATION);
136: aw.setASpellDictionary(ASPELL_DICTIONARY);
137: aw.setupAspell();
138: try {
139: BufferedReader in = new BufferedReader(new StringReader(
140: ASPELL_CONTENT));
141: HashMap hs = new HashMap();
142:
143: while ((inputLine = in.readLine()) != null) {
144: if (this .getLogger().isDebugEnabled()) {
145: this .getLogger()
146: .debug("Parsing line: " + inputLine);
147: }
148: XMLWordFinder finder = new XMLWordFinder(inputLine);
149: String aux = null;
150: while ((aux = finder.next()) != null) {
151: isValid = isValidString(aux);
152: if (this .getLogger().isDebugEnabled()) {
153: this .getLogger().debug(
154: "Parsing string: " + aux + "isValid: "
155: + isValid);
156: }
157: if (isValid) {
158: if (this .getLogger().isDebugEnabled()) {
159: this .getLogger().debug(
160: "findMostSimilar: "
161: + aux.toLowerCase());
162: }
163:
164: String aux2 = aw.findMostSimilar(aux
165: .toLowerCase());
166: List suggestions = aw.findMostSimilarList(aux);
167: if (aux2 == null) {
168: } else if (!aux2.equals(aux.toLowerCase())) {
169: if (suggestions.size() == 0) {
170: //System.out.println("\tNo suggestions");
171: }
172: hs = addToHashMap(hs, aux, suggestions);
173: }
174: }
175: }
176:
177: String newline = inputLine;
178: Iterator it = hs.keySet().iterator();
179: while (it.hasNext()) {
180: String word = it.next().toString();
181: newline = newline.replaceAll(word,
182: "<span class='HA-spellcheck-error'>" + word
183: + "</span>");
184: }
185: NEW_ASPELL_CONTENT += newline;
186: }
187: in.close();
188: Iterator it = hs.keySet().iterator();
189: while (it.hasNext()) {
190: String ts = it.next().toString();
191: contentHandler.startElement("", "MISSPELLED",
192: "MISSPELLED", emptyAttrs);
193: contentHandler.startElement("", "WORD", "WORD",
194: emptyAttrs);
195: contentHandler.characters(ts.toCharArray(), 0, ts
196: .length());
197: contentHandler.endElement("", "WORD", "WORD");
198: contentHandler.startElement("", "SUGGESTIONS",
199: "SUGGESTIONS", emptyAttrs);
200: List li = (List) hs.get(ts);
201: for (Iterator suggestedWord = li.iterator(); suggestedWord
202: .hasNext();) {
203: contentHandler.startElement("", "OTHER", "OTHER",
204: emptyAttrs);
205: String tmpWord = suggestedWord.next().toString();
206: contentHandler.characters(tmpWord.toCharArray(), 0,
207: tmpWord.length());
208: contentHandler.endElement("", "OTHER", "OTHER");
209: }
210: contentHandler.endElement("", "SUGGESTIONS",
211: "SUGGESTIONS");
212:
213: contentHandler.endElement("", "MISSPELLED",
214: "MISSPELLED");
215: }
216: } catch (Exception e) {
217: // TODO: handle exception
218: e.printStackTrace();
219: }
220: Vector dictionaries = aw.getDictionaries();
221: String startDiv = "<div id='HA-spellcheck-dictionaries'>";
222: String endDiv = "</div>";
223: String myDicts = "";
224: for (int ii = 0; ii < dictionaries.size(); ii++) {
225: String dic = dictionaries.get(ii).toString();
226: if (ii != dictionaries.size() - 1) {
227: myDicts += dic + ",";
228: } else {
229: myDicts += dic;
230: }
231: }
232: NEW_ASPELL_CONTENT += startDiv + myDicts + endDiv;
233: aw.cleanup();
234:
235: }
236:
237: public HashMap addToHashMap(HashMap hs, String s, List l) {
238: HashMap words = hs;
239: if (!words.containsKey(s)) {
240: words.put(s, l);
241: } else {
242: //System.out.println(s + " is already in there.");
243: }
244: return words;
245: }
246:
247: public static class ForwardHandler extends DefaultHandler {
248:
249: private XMLConsumer consumer = null;
250:
251: public ForwardHandler(XMLConsumer consumer) {
252: this .consumer = consumer;
253: }
254:
255: public void startElement(String s1, String s2, String s3,
256: Attributes a) throws SAXException {
257: consumer.startElement(s1, s2, s3, a);
258: }
259:
260: public void endElement(String s1, String s2, String s3)
261: throws SAXException {
262: consumer.endElement(s1, s2, s3);
263: }
264:
265: public void characters(char[] chars, int i1, int i2)
266: throws SAXException {
267: consumer.characters(chars, i1, i2);
268: }
269: }
270:
271: public static boolean isNumeric(char c) {
272: return c == '.' || (c == ',') || (c == '/') || (c == ':')
273: || (c >= '0' && c <= '9');
274: }
275:
276: public boolean isValidString(String checkString) {
277: for (int startIndex = 0; startIndex < checkString.length(); startIndex++) {
278: if (this .getLogger().isDebugEnabled()) {
279: this .getLogger().debug(
280: "Parsing character: "
281: + checkString.charAt(startIndex)
282: + " and return value: "
283: + Character.isLetter(checkString
284: .charAt(startIndex)));
285: }
286: if (!Character.isLetter(checkString.charAt(startIndex))) {
287: return false;
288: }
289: }
290: return true;
291: }
292:
293: }
|