001: /*
002: * Created on Feb 28, 2005
003: */
004: package com.sun.portal.wireless.htmlconversion.processors;
005:
006: import java.util.HashMap;
007:
008: import org.w3c.dom.Element;
009: import org.w3c.dom.Node;
010:
011: import com.sun.portal.wireless.htmlconversion.ParserState;
012: import com.sun.portal.wireless.htmlconversion.servlet.URLTranscoder;
013: import com.sun.portal.wireless.htmlconversion.servlet.URLScraper;
014:
015: /**
016: * Tag processor for AmlLink.
017: *
018: * Note that this may fail if text formatting elements are present
019: * in the HTML <a> tag body.
020: *
021: * @author ashwin.mathew@sun.com
022: */
023: public class AmlLinkTagProcessor extends BaseTagProcessor {
024:
025: public static final String AML_LINK = "AmlLink";
026:
027: public static final String HTML_ANCHOR = "a";
028:
029: private static final String[] supportedTags = { HTML_ANCHOR };
030:
031: // Attributes on AmlLink
032: public static final String ATTR_URL = "url";
033:
034: public static final String ATTR_TEXT = "text";
035:
036: // Attribute from <a> tag
037: public static final String ATTR_HREF = "href";
038:
039: private static final String EMPTY_STRING = "";
040:
041: /* (non-Javadoc)
042: * @see com.sun.portal.wireless.htmlconversion.TagProcessor#getAmlTag()
043: */
044: public String getAmlTag() {
045: return AML_LINK;
046: }
047:
048: /* (non-Javadoc)
049: * @see com.sun.portal.wireless.htmlconversion.TagProcessor#getSupportedTags()
050: */
051: public String[] getSupportedTags() {
052: return supportedTags;
053: }
054:
055: /* (non-Javadoc)
056: * @see com.sun.portal.wireless.htmlconversion.TagProcessor#canHaveChildren()
057: */
058: public boolean canHaveChildren(ParserState state) {
059: return true;
060: }
061:
062: /* (non-Javadoc)
063: * @see com.sun.portal.wireless.htmlconversion.TagProcessor#startTag(java.lang.String, java.util.HashMap, com.sun.portal.wireless.htmlconversion.ParserState)
064: */
065: public Element startTag(String tagName, HashMap attributes,
066: ParserState state) {
067: Element amlLink = state.newElement(AML_LINK);
068:
069: String href = (String) attributes.get(ATTR_HREF);
070:
071: if (href != null) {
072: String url = rewriteUrl(href, state);
073: amlLink.setAttribute(ATTR_URL, url);
074: }
075:
076: return amlLink;
077: }
078:
079: /* (non-Javadoc)
080: * @see com.sun.portal.wireless.htmlconversion.TagProcessor#endTag(java.lang.String, com.sun.portal.wireless.htmlconversion.ParserState)
081: */
082: public Element endTag(String tag, ParserState state) {
083: Element amlLink = state.getCurrentOutputTag();
084:
085: // If the AmlLink does not have a url attribute
086: // it must be removed from the output document.
087: // This is being done in endTag(), since if null
088: // is returned by startTag(), the output container
089: // tag context gets messed up, since the AmlLink will
090: // not be put onto the stack, but an attempt will be
091: // made to remove it on endTag().
092: String url = amlLink.getAttribute(ATTR_URL);
093: if (url == null || url.equals(EMPTY_STRING)) {
094: Node parent = amlLink.getParentNode();
095: parent.removeChild(amlLink);
096: return null;
097: }
098:
099: // Do this only if the AmlLink has more than one
100: // child, since AmlLink is allowed to have only
101: // a single AmlText or AmlImage child.
102: if (amlLink.getChildNodes().getLength() != 1) {
103: StringBuffer text = new StringBuffer();
104: Element amlLinkChild = null;
105:
106: // Iterate through the child list. If AmlText elements
107: // are found, append all the text values and output
108: // a single AmlText. If even one AmlImage element is
109: // found, output that in preference to AmlText.
110: Element child = (Element) amlLink.getFirstChild();
111: while (child != null) {
112: Element nextChild = (Element) child.getNextSibling();
113:
114: String tagName = child.getTagName();
115: if (tagName.equals(AmlImageTagProcessor.AML_IMAGE)) {
116: amlLinkChild = child;
117: } else if (tagName.equals(AmlTextTagProcessor.AML_TEXT)) {
118: text
119: .append(child
120: .getAttribute(AmlTextTagProcessor.ATTR_TEXT));
121: }
122:
123: amlLink.removeChild(child);
124:
125: child = nextChild;
126: }
127:
128: if (state.isTextAvailable()) {
129: text.append(state.getText());
130: state.clearText();
131: }
132:
133: if (amlLinkChild == null) {
134: // It's a text element
135: amlLinkChild = AmlTextTagProcessor
136: .createAmlTextElement(text.toString(), state);
137: }
138:
139: amlLink.appendChild(amlLinkChild);
140: }
141:
142: return null;
143: }
144:
145: /**
146: * Encodes the provided URL as a parameter to the HTML to AML
147: * transformation servlet path.
148: *
149: * @param url
150: * @return
151: */
152: public static final String rewriteUrl(String url, ParserState state) {
153: String rewriteUrl = null;
154: StringBuffer rewriteUrlBuffer = new StringBuffer();
155:
156: URLTranscoder encoder = state.getEncoder();
157:
158: if (encoder != null) {
159: rewriteUrl = encoder.rewriteURL(url);
160: } else {
161: // Not the right thing to be doing, but just do a best
162: // guess that the servlet context is "/portal".
163: rewriteUrlBuffer.append(URLScraper.DEFAULT_CONTEXT);
164: rewriteUrlBuffer.append(URLScraper.URL_PREFIX);
165: rewriteUrlBuffer.append(URLScraper.URL_PARAM);
166: rewriteUrlBuffer.append(URLTranscoder.EQUALS);
167: rewriteUrlBuffer.append(URLTranscoder.encode(url));
168:
169: rewriteUrl = rewriteUrlBuffer.toString();
170: }
171:
172: return rewriteUrl;
173: }
174:
175: }
|