| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Licensed 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 com.google.gwt.i18n.server; |
| |
| import java.util.List; |
| |
| /** |
| * Keeps track of control breaks for different forms of selectors, and calls |
| * begin/end Selector/Form methods on one or more {@link MessageFormVisitor} |
| * instances when appropriate. |
| */ |
| public class FormVisitorDriver { |
| |
| private int numSelectors; |
| private MessageFormVisitor[] formVisitors; |
| private String[] lastForm; |
| private int[] selectorParams; |
| private List<Parameter> params; |
| |
| /** |
| * Cleanup processing a message, including closing any outstanding |
| * {@link MessageFormVisitor} calls. Typically called from |
| * {@link MessageVisitor#endMessage(Message, MessageTranslation)}. |
| * |
| * @param msg |
| * @throws MessageProcessingException |
| */ |
| public void endMessage(Message msg) throws MessageProcessingException { |
| // close all outstanding selectors |
| for (int i = numSelectors; i-- > 0; ) { |
| if (lastForm[i] != null && formVisitors[i] != null) { |
| formVisitors[i].endForm(i, lastForm[i]); |
| formVisitors[i].endSelector(i, getSelectorParam(i)); |
| } |
| } |
| |
| formVisitors = null; |
| lastForm = null; |
| } |
| |
| /** |
| * Prepare for processing a new message. Typically called from |
| * {@link MessageInterfaceVisitor#visitMessage(Message, MessageTranslation)}. |
| * |
| * @param msg |
| */ |
| public void initialize(Message msg) { |
| initialize(msg, null); |
| } |
| |
| /** |
| * Prepare for processing a new message. Typically called from |
| * {@link MessageInterfaceVisitor#visitMessage(Message, MessageTranslation)}. |
| * |
| * @param msg |
| * @param formVisitor a single {@link MessageFormVisitor} to be used for all |
| * selector forms, or null if none or will be supplied later |
| */ |
| public void initialize(Message msg, MessageFormVisitor formVisitor) { |
| selectorParams = msg.getSelectorParameterIndices(); |
| numSelectors = selectorParams.length; |
| formVisitors = new MessageFormVisitor[numSelectors]; |
| lastForm = new String[numSelectors]; |
| params = msg.getParameters(); |
| if (formVisitor != null) { |
| for (int i = 0; i < numSelectors; ++i) { |
| formVisitors[i] = formVisitor; |
| } |
| } |
| } |
| |
| /** |
| * Set a visitor for forms at a particular selector level. Typically called |
| * from |
| * {@link MessageInterfaceVisitor#visitMessage(Message, MessageTranslation)}. |
| * |
| * @param level |
| * @param visitor |
| */ |
| public void setFormVisitor(int level, MessageFormVisitor visitor) { |
| formVisitors[level] = visitor; |
| } |
| |
| /** |
| * Call methods on supplied {@link MessageFormVisitor} instances according to |
| * which forms have changed. Typically called from |
| * {@link MessageVisitor#visitTranslation(String[], boolean, com.google.gwt.i18n.server.MessageFormatUtils.MessageStyle, String)}. |
| * |
| * @param formNames |
| * @throws MessageProcessingException |
| */ |
| public void visitForms(String[] formNames) |
| throws MessageProcessingException { |
| |
| // find where the changes were |
| int firstDifferent = 0; |
| while (firstDifferent < numSelectors && formNames[ |
| firstDifferent].equals(lastForm[firstDifferent])) { |
| ++firstDifferent; |
| } |
| |
| // close nested selectors/forms deeper than the change |
| for (int i = numSelectors; i-- > firstDifferent; ) { |
| if (lastForm[i] != null && formVisitors[i] != null) { |
| formVisitors[i].endForm(i, lastForm[i]); |
| if (i > firstDifferent) { |
| formVisitors[i].endSelector(i, getSelectorParam(i)); |
| } |
| } |
| } |
| |
| // open all nested selectors from here |
| for (int i = firstDifferent; i < numSelectors; ++i) { |
| if ((i > firstDifferent || lastForm[i] == null) |
| && formVisitors[i] != null) { |
| formVisitors[i].beginSelector(i, getSelectorParam(i)); |
| } |
| lastForm[i] = formNames[i]; |
| if (formVisitors[i] != null) { |
| formVisitors[i].beginForm(i, lastForm[i]); |
| } |
| } |
| } |
| |
| private Parameter getSelectorParam(int i) { |
| int index = selectorParams[i]; |
| return index < 0 ? null : params.get(index); |
| } |
| } |