001: /*
002: * Copyright 2004 Clinton Begin
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 com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
017:
018: import com.ibatis.common.beans.Probe;
019: import com.ibatis.common.beans.ProbeFactory;
020:
021: public class IterateTagHandler extends BaseTagHandler {
022:
023: private static final Probe PROBE = ProbeFactory.getProbe();
024:
025: public int doStartFragment(SqlTagContext ctx, SqlTag tag,
026: Object parameterObject) {
027: IterateContext iterate = (IterateContext) ctx.getAttribute(tag);
028: if (iterate == null) {
029: IterateContext parentIterate = ctx.peekIterateContext();
030:
031: ctx.pushRemoveFirstPrependMarker(tag);
032:
033: Object collection;
034: String prop = tag.getPropertyAttr();
035: if (prop != null && !prop.equals("")) {
036: if (null != parentIterate
037: && parentIterate.isAllowNext()) {
038: parentIterate.next();
039: parentIterate.setAllowNext(false);
040: if (!parentIterate.hasNext()) {
041: parentIterate.setFinal(true);
042: }
043: }
044:
045: if (parentIterate != null) {
046: prop = parentIterate.addIndexToTagProperty(prop);
047: }
048:
049: collection = PROBE.getObject(parameterObject, prop);
050: } else {
051: collection = parameterObject;
052: }
053: iterate = new IterateContext(collection, tag, parentIterate);
054:
055: iterate.setProperty(null == prop ? "" : prop);
056:
057: ctx.setAttribute(tag, iterate);
058: ctx.pushIterateContext(iterate);
059: } else if ("iterate".equals(tag.getRemoveFirstPrepend())) {
060: ctx.reEnableRemoveFirstPrependMarker();
061: }
062:
063: if (iterate != null && iterate.hasNext()) {
064: return INCLUDE_BODY;
065: } else {
066: return SKIP_BODY;
067: }
068: }
069:
070: public int doEndFragment(SqlTagContext ctx, SqlTag tag,
071: Object parameterObject, StringBuffer bodyContent) {
072: IterateContext iterate = (IterateContext) ctx.getAttribute(tag);
073:
074: if (iterate.hasNext() || iterate.isFinal()) {
075:
076: if (iterate.isAllowNext()) {
077: iterate.next();
078: }
079:
080: if (bodyContent.toString().trim().length() > 0) {
081: // the sub element produced a result. If it is the first one
082: // to produce a result, then we need to add the open
083: // text. If it is not the first to produce a result then
084: // we need to add the conjunction text
085: if (iterate.someSubElementsHaveContent()) {
086: if (tag.isConjunctionAvailable()) {
087: bodyContent.insert(0, tag.getConjunctionAttr());
088: }
089: } else {
090: // we need to specify that this is the first content
091: // producing element so that the doPrepend method will
092: // add the prepend
093: iterate.setPrependEnabled(true);
094:
095: if (tag.isOpenAvailable()) {
096: bodyContent.insert(0, tag.getOpenAttr());
097: }
098: }
099: iterate.setSomeSubElementsHaveContent(true);
100: }
101:
102: if (iterate.isLast()
103: && iterate.someSubElementsHaveContent()) {
104: if (tag.isCloseAvailable()) {
105: bodyContent.append(tag.getCloseAttr());
106: }
107: }
108:
109: iterate.setAllowNext(true);
110: if (iterate.isFinal()) {
111: return super .doEndFragment(ctx, tag, parameterObject,
112: bodyContent);
113: } else {
114: return REPEAT_BODY;
115: }
116:
117: } else {
118: return super .doEndFragment(ctx, tag, parameterObject,
119: bodyContent);
120: }
121: }
122:
123: public void doPrepend(SqlTagContext ctx, SqlTag tag,
124: Object parameterObject, StringBuffer bodyContent) {
125: IterateContext iterate = (IterateContext) ctx.getAttribute(tag);
126: if (iterate.isPrependEnabled()) {
127: super .doPrepend(ctx, tag, parameterObject, bodyContent);
128: iterate.setPrependEnabled(false); // only do the prepend one time
129: }
130: }
131:
132: public boolean isPostParseRequired() {
133: return true;
134: }
135:
136: }
|