/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.cg.templates; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.toolbox.StringUtils; public abstract class CGTemplateSet extends CGTemplateObject { protected static final Logger logger = Logger.getLogger(CGTemplateSet.class.getPackage().getName()); private Hashtable<String, CGTemplate> templates; private CGTemplateRepository _repository; private boolean isUpdating = false; private CGTemplateFolder rootFolder; public CGTemplateSet(CGTemplateRepository repository) { super(); _repository = repository; templates = new Hashtable<String, CGTemplate>(); rootFolder = new CGTemplateFolder(this, getRootFolderName()) { @Override public String getName() { return getRootFolderName(); } }; } public String getRootFolderName() { return getName(); } public CGTemplateFolder getRootFolder() { return rootFolder; } protected void registerTemplate(CGTemplate template) { CGTemplateFolder folder = retrieveFolder(template.getFolderPath()); folder.templates.add(template); } protected void unregisterTemplate(CGTemplate template) { CGTemplateFolder folder = retrieveFolder(template.getFolderPath()); folder.templates.remove(template); } private CGTemplateFolder retrieveFolder(String folderPath) { if (StringUtils.isEmpty(folderPath)) { return getRootFolder(); } StringTokenizer st = new StringTokenizer(folderPath, "/" + File.separator); CGTemplateFolder current = getRootFolder(); while (st.hasMoreElements()) { String next = st.nextToken(); if (current.getFolder(next) == null) { CGTemplateFolder newFolder = new CGTemplateFolder(this, next); current.dirs.add(newFolder); current = newFolder; } else { current = current.getFolder(next); } } return current; } @Override public void update() { if (isUpdating) { return; } // logger.info("********** Updating templates for directory "+_directory.getAbsolutePath()); try { Set<String> previousKnownTemplates = new HashSet<String>(templates.keySet()); CGTemplate[] newTemplates = findAllTemplates(); if (newTemplates != null) { for (CGTemplate template : newTemplates) { String relativePath = template.getRelativePathWithoutSetPrefix(); if (templates.get(relativePath) == null) { // logger.info(">>>> Adding file "+file.getAbsolutePath()+" relative path = "+relativePath); templates.put(relativePath, template); registerTemplate(template); } if (previousKnownTemplates.contains(relativePath)) { previousKnownTemplates.remove(relativePath); } } } for (String templateRelativePath : previousKnownTemplates) { CGTemplate template = templates.get(templateRelativePath); if (template == null) { continue; // GPO: see bug 1007011 (this should not happen because I prevented recursion from happening with flag // isUpdating, but I leave this just to be really sure that no NPE } // will occur) if (!template.isDeleted()) { template.delete(); } if (logger.isLoggable(Level.INFO)) { logger.info("Removing " + templateRelativePath); } templates.remove(templateRelativePath); unregisterTemplate(template); } for (CGTemplate template : templates.values()) { if (template.getIsVersionOnDiskSeemsNewer()) { logger.fine("Updating file: " + template.getRelativePath()); template.update(true); } } } finally { isUpdating = false; } } /** * Returns all templates associated to this set. * * @return all templates associated to this set. */ protected abstract CGTemplate[] findAllTemplates(); @Override public FlexoProject getProject() { return _repository.getProject(); } @Override public String getClassNameKey() { return "template_set"; } public Enumeration<CGTemplate> getAllTemplates() { return templates.elements(); } public Enumeration<CGTemplate> getSortedTemplates() { Vector<CGTemplate> sortedTemplates = new Vector<CGTemplate>(templates.values()); Collections.sort(sortedTemplates, new CGTemplate.CGTemplateComparator()); return sortedTemplates.elements(); } // TODO: optimize this public List<CGTemplate> getTemplateList() { List<CGTemplate> sortedTemplates = new ArrayList<CGTemplate>(templates.values()); Collections.sort(sortedTemplates, new CGTemplate.CGTemplateComparator()); return sortedTemplates; } public CGTemplateRepository getRepository() { return _repository; } @Override public CGTemplates getTemplates() { return getRepository().getTemplates(); } public CGTemplate getTemplate(String templateRelativePath) { return templates.get(templateRelativePath); } @Override public abstract String getName(); }