[Seasar-user:3667] Re: S2JSF validatorについて

O.Goto [E-MAIL ADDRESS DELETED]
2006年 5月 20日 (土) 09:10:37 JST


後藤です。

On Sat, 20 May 2006 01:30:29 +0900
"Shinpei Ohtani" <[E-MAIL ADDRESS DELETED]> wrote:

> shotです。
> 
> > というわけで、<textarea>の子要素としてバリデータを追加できるようにして欲しいという要望を挙げておきます。
> > <textarea>だけできないというのは優しくないかなと感じます。
> > 一応自分でTagProcessorHandlerに手を入れて<textarea>の子要素にバリデータを追加できるようにしてみました。
> > でも場当たり的な直しになってしまったので、動くことは動くのですがとても美しいとは言えない状態です。
> > 今のところは元に戻して、上記で教えていただいた<textarea>の属性としてバリデータを指定することにしました。
> 
> 後藤さんが手を入れた方法は、
> 
> 1)<textarea>の子要素をPCDATAに加えて<span>も追加した改変DTDでパースする。
> 2)TagProcessorHandler#characters()でpeekProcessor()の戻りがInputTextareaProcessorの時に
> textがバリデータかどうかチェックしてバリデータならValidatorProcessorを作成してaddChild()する。
> 
> の2)の方法でしょうか?
> 
はい。2)の方法です。

> 美しいかどうかよりも、ニーズが満たせるかどうかの方が大事だと思っているので、
> もしよければ教えてください。それを元にS2JSFに修正を入れるか検討してみますので。
> 
以下は今回修正したパッチです。
自分で見ても恥ずかしい(笑)。
今回の私の修正は本当に場当たりな修正なので、TagProcessorTreeFactoryImplも
巻き込んで直した方がいいと思っています。
他にももっと良い方法があるように思えますし。

patch start ----------------------------
Index: /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/processor/InputTextareaProcessor.java
===================================================================
--- /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/processor/InputTextareaProcessor.java	(revision 2)
+++ /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/processor/InputTextareaProcessor.java	(working copy)
@@ -28,7 +28,8 @@
 	}
 
 	public void addChild(TagProcessor child) {
-		if (child instanceof TextProcessor) {
+		if (child instanceof TextProcessor
+				|| !(child instanceof ValidatorProcessor)) {
 			return;
 		}
 		super.addChild(child);
Index: /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/processor/SelectProcessor.java
===================================================================
--- /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/processor/SelectProcessor.java	(revision 2)
+++ /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/processor/SelectProcessor.java	(working copy)
@@ -30,7 +30,8 @@
 
 	public void addChild(TagProcessor child) {
 		if (child instanceof TextProcessor
-				|| getProperty(JsfConstants.ITEMS_ATTR) != null) {
+				|| ((!(child instanceof ValidatorProcessor)) &&
+					getProperty(JsfConstants.ITEMS_ATTR) != null)) {
 			return;
 		}
 		super.addChild(child);
Index: /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/runtime/TagProcessorHandler.java
===================================================================
--- /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/runtime/TagProcessorHandler.java	(revision 2)
+++ /home/o-goto/eclipse/workspace/s2jsf/src/main/java/org/seasar/jsf/runtime/TagProcessorHandler.java	(working copy)
@@ -15,8 +15,12 @@
  */
 package org.seasar.jsf.runtime;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.util.Stack;
 
+import org.seasar.framework.exception.IORuntimeException;
+import org.seasar.framework.exception.SAXRuntimeException;
 import org.seasar.jsf.JsfConfig;
 import org.seasar.jsf.JsfConstants;
 import org.seasar.jsf.TagProcessor;
@@ -23,11 +27,17 @@
 import org.seasar.jsf.TagSelector;
 import org.seasar.jsf.ViewTemplateFactory;
 import org.seasar.jsf.processor.ElementProcessor;
+import org.seasar.jsf.processor.InputTextareaProcessor;
 import org.seasar.jsf.processor.TextProcessor;
+import org.seasar.jsf.processor.ValidatorProcessor;
 import org.seasar.jsf.processor.ViewProcessor;
 import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.DefaultHandler;
 
 public class TagProcessorHandler extends DefaultHandler {
@@ -102,6 +112,18 @@
 	}
     
     protected void addText(TagProcessor processor, String text) {
+    	if (processor instanceof InputTextareaProcessor) {
+    		try {
+        		TagProcessor child = getChildProcessorForTextarea(text, processor);
+        		if (child != null) {
+        			return;
+        		}
+    		} catch (SAXException e) {
+    			throw new SAXRuntimeException(e);
+    		} catch (IOException e) {
+    			throw new IORuntimeException(e);
+    		}
+    	}
         TagProcessor child = getPreviousChildProcessor(processor);
         if (child instanceof ElementProcessor) {
             ((ElementProcessor) child).addAfterContents(text);
@@ -138,4 +160,47 @@
 	public void warning(SAXParseException e) throws SAXException {
 		System.err.println(e);
 	}
+
+	private TagProcessor getChildProcessorForTextarea(String text, final TagProcessor parentProcessor) throws SAXException, IOException {
+		if (text.trim().length() == 0) {
+			return null;
+		}
+		String html = "<html xmlns:m=\"http://www.seasar.org/maya\">" +
+			"<head/><body><form><input type=\"text\">" +
+			text + "</input></form></body></html>";
+		final TagProcessor[] tagProcessors = new TagProcessor[1];
+		tagProcessors[0] = null;
+		XMLReader reader = new TagProcessorTreeFactoryImpl().createReader();
+		reader.setContentHandler(new ContentHandler() {
+			public void endDocument() throws SAXException {}
+			public void startDocument() throws SAXException {}
+			public void characters(char[] ch, int start, int length) throws SAXException {}
+			public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {}
+			public void endPrefixMapping(String prefix) throws SAXException {}
+			public void skippedEntity(String name) throws SAXException {}
+			public void setDocumentLocator(Locator locator) {}
+			public void processingInstruction(String target, String data) throws SAXException {}
+			public void startPrefixMapping(String prefix, String uri) throws SAXException {}
+			public void endElement(String namespaceURI, String localName, String qName) throws SAXException {}
+			public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) throws SAXException {
+				if (tagProcessors[0] != null || !localName.equals("span")) {
+					return;
+				}
+				TagSelector selector = tagSelectors.getTagSelector(namespaceURI,
+						localName, qName, attributes);
+				if (selector == null) {
+					return;
+				}
+				TagProcessor processor = selector.createProcessor();
+				if (!(processor instanceof ValidatorProcessor)) {
+					return;
+				}
+				parentProcessor.addChild(processor);
+				processor.setup(namespaceURI, localName, qName, attributes, jsfConfig);
+				tagProcessors[0] = processor;
+			}});
+			reader.parse(new InputSource(new ByteArrayInputStream(html.getBytes())));
+		return tagProcessors[0];
+	}
+
 }

patch end----------------------------



Seasar-user メーリングリストの案内