/* * Copyright (c) 2011-2014 Fernando Petrola * * 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.dragome.templates; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.dragome.guia.GuiaServiceLocator; import com.dragome.render.ItemProcessorImpl; import com.dragome.render.interfaces.ItemProcessor; import com.dragome.render.interfaces.TemplateHandler; import com.dragome.render.interfaces.View; import com.dragome.templates.interfaces.SimpleItemProcessor; import com.dragome.templates.interfaces.Template; public class TemplateRepeater<T> { private List<T> items; private ItemProcessor<T> itemProcessor; private Map<T, List<Template>> templatesByItem= new LinkedHashMap<T, List<Template>>(); private LinkedHashMap<T, List<Template>> shownTemplates= new LinkedHashMap<T, List<Template>>(); private boolean updating= false; public TemplateRepeater() { } public TemplateRepeater(boolean updating) { this.updating= updating; } public TemplateRepeater(List<T> items, final ItemProcessor<T> itemProcessor) { this.items= items; this.itemProcessor= itemProcessor; } public TemplateRepeater(List<T> items, Template mainTemplate, String subTemplateName, final SimpleItemProcessor<T> simpleItemProcessor, boolean updating) { this.updating= updating; this.items= items; itemProcessor= new ItemProcessorImpl<T>(mainTemplate, subTemplateName) { public void fillTemplate(T item, Template aTemplate) { simpleItemProcessor.fillTemplate(item, aTemplate); } }; } public void repeatItems() { repeatItems(items, itemProcessor); } public void clearAndRepeatItems() { // for (Entry<T, List<Template>> entry : templatesByItem.entrySet()) // { // for (Template template : entry.getValue()) // { // if (template.getParent() != null) // template.getParent().remove(template); // } // } // // templatesByItem.clear(); repeatItems(items, itemProcessor); } public void repeatItems(Iterable<T> items, ItemProcessor<T> itemProcessor) { Map<T, List<Template>> templatesByItemReplacement= new LinkedHashMap<T, List<Template>>(); TemplateHandler templateHandler= GuiaServiceLocator.getInstance().getTemplateHandler(); Entry<T, List<Template>> entry= null; Iterator<Entry<T, List<Template>>> entriesIterator= shownTemplates.entrySet().iterator(); if (updating) { if (!shownTemplates.isEmpty()) entry= entriesIterator.next(); } for (T item : items) { List<Template> templatesOfItem= templatesByItem.get(item); if (templatesOfItem == null || templatesOfItem.isEmpty()) { List<Template> repeatChildren= itemProcessor.getRepeatTemplates(item); for (Template template : repeatChildren) templateHandler.makeInvisible(template); templatesOfItem= templateHandler.cloneTemplates(repeatChildren); insertTemplates(itemProcessor, item, templatesOfItem, entry); for (Template repeatChild : templatesOfItem) templateHandler.makeVisible(repeatChild); itemProcessor.fillTemplates(item, templatesOfItem); if (templatesOfItem.size() == 1) itemProcessor.fillTemplate(item, templatesOfItem.get(0)); } else if (entry == null || !entry.getKey().equals(item)) insertTemplates(itemProcessor, item, templatesOfItem, entry); templatesByItemReplacement.put(item, templatesOfItem); if (updating) if (entriesIterator.hasNext()) { if (entry == null || entry.getKey().equals(item)) entry= entriesIterator.next(); } else entry= null; } shownTemplates= new LinkedHashMap<T, List<Template>>(templatesByItemReplacement); if (updating) { for (Entry<T, List<Template>> entry2 : templatesByItem.entrySet()) { if (!templatesByItemReplacement.containsKey(entry2.getKey())) { templatesByItemReplacement.put(entry2.getKey(), entry2.getValue()); for (Template template : entry2.getValue()) { if (template.getParent() != null) template.getParent().remove(template); } } } templatesByItem= templatesByItemReplacement; } } private void insertTemplates(ItemProcessor<T> itemProcessor, T item, List<Template> clonedRepeatChildren, Entry<T, List<Template>> entry) { Template insertChild= entry != null ? entry.getValue().get(0) : itemProcessor.getInsertTemplate(item); for (Template clonedRepeatedChild : clonedRepeatChildren) { clonedRepeatedChild.setName(clonedRepeatedChild.getName() + "_" + Integer.toHexString((int) System.currentTimeMillis())); insertChild.getParent().insertBefore(clonedRepeatedChild, insertChild); } } public ItemProcessorImpl<T> createItemAdder(Template aTemplate, final Template originalTemplate, final List<? extends View<T>> modelViews, String insertionPoint) { return new ItemProcessorImpl<T>(aTemplate, insertionPoint) { public void fillTemplates(final T item, List<Template> aRowTemplate) { View<T> result= findViewFor(item); result.composeView(item, aRowTemplate); } public List<Template> getRepeatTemplates(T item) { View<T> result= findViewFor(item); return result.getRequiredSubTemplates(originalTemplate); } private View<T> findViewFor(T item) { for (View<T> modelView : modelViews) if (modelView.match(item, originalTemplate)) return modelView; return null; } }; } public Template getUpdatedTemplateFor(T item) { TemplateHandler templateHandler= GuiaServiceLocator.getInstance().getTemplateHandler(); Template updatedTemplate= itemProcessor.getRepeatTemplates(item).get(0); Template clone= templateHandler.clone(updatedTemplate); templateHandler.makeVisible(clone); templatesByItem.get(item).add(clone); return clone; } }