| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.struts2.components; |
| |
| import com.opensymphony.xwork2.util.ValueStack; |
| import org.apache.logging.log4j.LogManager; |
| import org.apache.logging.log4j.Logger; |
| import org.apache.struts2.components.Param.UnnamedParametric; |
| import org.apache.struts2.util.MakeIterator; |
| import org.apache.struts2.util.MergeIteratorFilter; |
| import org.apache.struts2.views.annotations.StrutsTag; |
| import org.apache.struts2.views.annotations.StrutsTagAttribute; |
| |
| import java.io.Writer; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * <!-- START SNIPPET: javadoc --> |
| * <p>Component for MergeIteratorTag, which job is to merge iterators and successive |
| * call to the merged iterator will cause each merge iterator to have a chance to |
| * expose its element, subsequently next call will allow the next iterator to expose |
| * its element. Once the last iterator is done exposing its element, the first iterator |
| * is allowed to do so again (unless it is exhausted of entries).</P> |
| * |
| * <p>Internally the task are delegated to MergeIteratorFilter</p> |
| * |
| * <p>Example if there are 3 lists being merged, each list have 3 entries, the following will |
| * be the logic.</P> |
| * <ol> |
| * <li>Display first element of the first list</li> |
| * <li>Display first element of the second list</li> |
| * <li>Display first element of the third list</li> |
| * <li>Display second element of the first list</li> |
| * <li>Display second element of the second list</li> |
| * <li>Display second element of the third list</li> |
| * <li>Display third element of the first list</li> |
| * <li>Display thrid element of the second list</li> |
| * <li>Display third element of the thrid list</li> |
| * </ol> |
| * <!-- END SNIPPET: javadoc --> |
| * |
| * <!-- START SNIPPET: params --> |
| * <ul> |
| * <li>var (String) - the name where the resultant merged iterator will be stored in the stack's context</li> |
| * </ul> |
| * <!-- END SNIPPET: params --> |
| * |
| * |
| * <!-- START SNIPPET: javacode --> |
| * public class MergeIteratorTagAction extends ActionSupport { |
| * |
| * private List myList1; |
| * private List myList2; |
| * private List myList3; |
| * |
| * public List getMyList1() { |
| * return myList1; |
| * } |
| * |
| * public List getMyList2() { |
| * return myList2; |
| * } |
| * |
| * public List getMyList3() { |
| * return myList3; |
| * } |
| * |
| * |
| * public String execute() throws Exception { |
| * |
| * myList1 = new ArrayList(); |
| * myList1.add("1"); |
| * myList1.add("2"); |
| * myList1.add("3"); |
| * |
| * myList2 = new ArrayList(); |
| * myList2.add("a"); |
| * myList2.add("b"); |
| * myList2.add("c"); |
| * |
| * myList3 = new ArrayList(); |
| * myList3.add("A"); |
| * myList3.add("B"); |
| * myList3.add("C"); |
| * |
| * return "done"; |
| * } |
| * } |
| * <!-- END SNIPPET: javacode --> |
| * |
| * <!-- START SNIPPET: example --> |
| * <s:merge var="myMergedIterator1"> |
| * <s:param value="%{myList1}" /> |
| * <s:param value="%{myList2}" /> |
| * <s:param value="%{myList3}" /> |
| * </s:merge> |
| * <s:iterator value="%{#myMergedIterator1}"> |
| * <s:property /> |
| * </s:iterator> |
| * <!-- END SNIPPET: example --> |
| * |
| * <!-- START SNIPPET: description --> |
| * This wil generate "1aA2bB3cC". |
| * <!-- START SNIPPET: description --> |
| * |
| * @see org.apache.struts2.util.MergeIteratorFilter |
| * @see org.apache.struts2.views.jsp.iterator.MergeIteratorTag |
| * |
| */ |
| @StrutsTag(name="merge", tldTagClass="org.apache.struts2.views.jsp.iterator.MergeIteratorTag", description="Merge the values " + |
| "of a list of iterators into one iterator") |
| public class MergeIterator extends ContextBean implements UnnamedParametric { |
| |
| private static final Logger LOG = LogManager.getLogger(MergeIterator.class); |
| |
| private MergeIteratorFilter mergeIteratorFilter = null; |
| private List _parameters; |
| |
| public MergeIterator(ValueStack stack) { |
| super(stack); |
| } |
| |
| public boolean start(Writer writer) { |
| |
| mergeIteratorFilter = new MergeIteratorFilter(); |
| _parameters = new ArrayList(); |
| |
| return super.start(writer); |
| } |
| |
| public boolean end(Writer writer, String body) { |
| |
| for (Object iteratorEntryObj : _parameters) { |
| if (! MakeIterator.isIterable(iteratorEntryObj)) { |
| LOG.warn("param with value resolved as {} cannot be make as iterator, it will be ignored and hence will not appear in the merged iterator", iteratorEntryObj); |
| continue; |
| } |
| mergeIteratorFilter.setSource(MakeIterator.convert(iteratorEntryObj)); |
| } |
| |
| mergeIteratorFilter.execute(); |
| |
| // if id exists, we put it in the stack's context |
| putInContext(mergeIteratorFilter); |
| |
| mergeIteratorFilter = null; |
| |
| return super.end(writer, body); |
| } |
| |
| @StrutsTagAttribute(description="The name where the resultant merged iterator will be stored in the stack's context") |
| public void setVar(String var) { |
| super.setVar(var); |
| } |
| |
| // == UnnamedParametric interface implementation --------------------- |
| public void addParameter(Object value) { |
| _parameters.add(value); |
| } |
| } |