/******************************************************************************* * Copyright (c) 2004, 2013 Spring IDE Developers * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.core.internal.project; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.springframework.ide.eclipse.beans.core.BeansCorePlugin; import org.springframework.ide.eclipse.beans.core.internal.model.BeansConfigSet; import org.springframework.ide.eclipse.beans.core.internal.model.BeansProject; import org.springframework.ide.eclipse.beans.core.model.IBeansConfig; import org.springframework.ide.eclipse.beans.core.model.IBeansConfigSet; import org.springframework.ide.eclipse.beans.core.model.IBeansProject; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** * This class provides a SAX handler for a Spring project's description file. * @author Torsten Juergeleit * @author Christian Dupuis * @author Martin Lippert */ public class BeansProjectDescriptionHandler extends DefaultHandler implements IBeansProjectDescriptionConstants { protected enum State { INITIAL, PROJECT_DESC, CONFIG_EXTENSIONS, CONFIG_EXTENSION, CONFIG_SUFFIXES, CONFIG_SUFFIX, CONFIGS, AUTOCONFIGS, CONFIG, AUTOCONFIG, CONFIG_SETS, CONFIG_SET, CONFIG_SET_NAME, CONFIG_SET_OVERRIDING, CONFIG_SET_INCOMPLETE, CONFIG_SET_CONFIGS,CONFIG_SET_CONFIG, VERSION, PLUGIN_VERSION, ENABLE_IMPORTS, PROFILES, PROFILE } protected BeansProject project; protected MultiStatus problems; protected State state; protected BeansConfigSet configSet; protected final StringBuffer charBuffer = new StringBuffer(); protected Locator locator; public BeansProjectDescriptionHandler(BeansProject project) { this.project = project; problems = new MultiStatus(BeansCorePlugin.PLUGIN_ID, IResourceStatus.FAILED_READ_METADATA, "Error reading Spring project description", null); state = State.INITIAL; } public IStatus getStatus() { return problems; } @Override public void startElement(String uri, String elementName, String qname, Attributes attributes) throws SAXException { // clear the character buffer at the start of every element charBuffer.setLength(0); if (state == State.INITIAL) { if (elementName.equals(PROJECT_DESCRIPTION)) { state = State.PROJECT_DESC; } else { throw new SAXParseException("No Spring project description", locator); } } else if (state == State.PROJECT_DESC) { if (elementName.equals(CONFIG_EXTENSIONS)) { state = State.CONFIG_EXTENSIONS; } else if (elementName.equals(CONFIG_SUFFIXES)) { state = State.CONFIG_SUFFIXES; } else if (elementName.equals(CONFIGS)) { state = State.CONFIGS; } else if (elementName.equals(AUTOCONFIGS)) { state = State.AUTOCONFIGS; project.setAutoConfigStatePersisted(true); } else if (elementName.equals(CONFIG_SETS)) { state = State.CONFIG_SETS; } else if (elementName.equals(ENABLE_IMPORTS)) { state = State.ENABLE_IMPORTS; } else if (elementName.equals(PLUGIN_VERSION)) { state = State.PLUGIN_VERSION; } } else if (state == State.CONFIG_EXTENSIONS) { if (elementName.equals(CONFIG_EXTENSION)) { state = State.CONFIG_EXTENSION; } } else if (state == State.CONFIG_SUFFIXES) { if (elementName.equals(CONFIG_SUFFIX)) { state = State.CONFIG_SUFFIX; } } else if (state == State.ENABLE_IMPORTS) { if (elementName.equals(ENABLE_IMPORTS)) { state = State.ENABLE_IMPORTS; } } else if (state == State.CONFIGS) { if (elementName.equals(CONFIG)) { state = State.CONFIG; } } else if (state == State.AUTOCONFIGS) { if (elementName.equals(AUTOCONFIG)) { state = State.AUTOCONFIG; } } else if (state == State.CONFIG_SETS) { if (elementName.equals(CONFIG_SET)) { state = State.CONFIG_SET; } } else if (state == State.CONFIG_SET) { if (elementName.equals(NAME)) { state = State.CONFIG_SET_NAME; } else if (elementName.equals(OVERRIDING)) { state = State.CONFIG_SET_OVERRIDING; } else if (elementName.equals(INCOMPLETE)) { state = State.CONFIG_SET_INCOMPLETE; } else if (elementName.equals(CONFIGS)) { state = State.CONFIG_SET_CONFIGS; } else if (elementName.equals(PROFILES)) { state = State.PROFILES; } } else if (state == State.CONFIG_SET_CONFIGS) { if (elementName.equals(CONFIG)) { state = State.CONFIG_SET_CONFIG; } } else if (state == State.PROFILES) { if (elementName.equals(PROFILE)) { state = State.PROFILE; } } } @Override public void endElement(String uri, String elementName, String qname) throws SAXException { if (state == State.PROJECT_DESC) { // make sure that at least the default config suffix is in // the list of config suffix if (project.getConfigSuffixes().isEmpty()) { project.addConfigSuffix(IBeansProject .DEFAULT_CONFIG_SUFFIX); } } else if (state == State.CONFIG_EXTENSIONS) { if (elementName.equals(CONFIG_EXTENSIONS)) { state = State.PROJECT_DESC; } } else if (state == State.ENABLE_IMPORTS) { if (elementName.equals(ENABLE_IMPORTS)) { boolean isImportEnabled = Boolean.valueOf(charBuffer.toString().trim()); project.setImportsEnabled(isImportEnabled); state = State.PROJECT_DESC; } } else if (state == State.PLUGIN_VERSION) { if (elementName.equals(PLUGIN_VERSION)) { String version = charBuffer.toString().trim(); project.setVersion(version); state = State.PROJECT_DESC; } } else if (state == State.CONFIG_SUFFIXES) { if (elementName.equals(CONFIG_SUFFIXES)) { state = State.PROJECT_DESC; } } else if (state == State.CONFIG_EXTENSION) { if (elementName.equals(CONFIG_EXTENSION)) { String extension = charBuffer.toString().trim(); project.addConfigSuffix(extension); state = State.CONFIG_EXTENSIONS; } } else if (state == State.CONFIG_SUFFIX) { if (elementName.equals(CONFIG_SUFFIX)) { String extension = charBuffer.toString().trim(); project.addConfigSuffix(extension); state = State.CONFIG_SUFFIXES; } } else if (state == State.CONFIGS) { if (elementName.equals(CONFIGS)) { state = State.PROJECT_DESC; } } else if (state == State.AUTOCONFIGS) { if (elementName.equals(AUTOCONFIGS)) { state = State.PROJECT_DESC; } } else if (state == State.CONFIG) { if (elementName.equals(CONFIG)) { String config = charBuffer.toString().trim(); // If given config is a full path within this Spring // project then convert it to a project relative path if (config.length() > 0 && config.charAt(0) == '/') { String projectPath = '/' + project.getElementName() + '/'; if (config.startsWith(projectPath)) { config = config.substring(projectPath.length()); } } project.addConfig(config, IBeansConfig.Type.MANUAL); state = State.CONFIGS; } } else if (state == State.AUTOCONFIG) { if (elementName.equals(AUTOCONFIG)) { // TODO: set auto configs correctly state = State.AUTOCONFIGS; } } else if (state == State.CONFIG_SETS) { if (elementName.equals(CONFIG_SETS)) { state = State.PROJECT_DESC; } } else if (state == State.CONFIG_SET) { if (elementName.equals(CONFIG_SET)) { project.addConfigSet(configSet); state = State.CONFIG_SETS; } } else if (state == State.PROFILES) { if (elementName.equals(PROFILES)) { state = State.CONFIG_SET; } } else if (state == State.PROFILE) { if (elementName.equals(PROFILE)) { String profile = charBuffer.toString().trim(); configSet.addProfile(profile); state = State.PROFILES; } } else if (state == State.CONFIG_SET_NAME) { if (elementName.equals(NAME)) { String name = charBuffer.toString().trim(); configSet = new BeansConfigSet(project, name, IBeansConfigSet.Type.MANUAL); state = State.CONFIG_SET; } } else if (state == State.CONFIG_SET_OVERRIDING) { if (elementName.equals(OVERRIDING)) { boolean override = Boolean .valueOf(charBuffer.toString().trim()).booleanValue(); configSet.setAllowBeanDefinitionOverriding(override); state = State.CONFIG_SET; } } else if (state == State.CONFIG_SET_INCOMPLETE) { if (elementName.equals(INCOMPLETE)) { boolean incomplete = Boolean.valueOf( charBuffer.toString().trim()).booleanValue(); configSet.setIncomplete(incomplete); state = State.CONFIG_SET; } } else if (state == State.CONFIG_SET_CONFIGS) { if (elementName.equals(CONFIGS)) { state = State.CONFIG_SET; } } else if (state == State.CONFIG_SET_CONFIG) { if (elementName.equals(CONFIG)) { String config = charBuffer.toString().trim(); // If given config is a full path within this Spring // project then convert it to a project relative path if (config.length() > 0 && config.charAt(0) == '/') { String projectPath = '/' + project.getElementName() + '/'; if (config.startsWith(projectPath)) { config = config.substring(projectPath.length()); } } configSet.addConfig(config); state = State.CONFIG_SET_CONFIGS; } } charBuffer.setLength(0); } @Override public void characters(char[] chars, int offset, int length) throws SAXException { // accumulate characters and process them when endElement is reached charBuffer.append(chars, offset, length); } @Override public void setDocumentLocator(Locator locator) { this.locator = locator; } @Override public void error(SAXParseException error) throws SAXException { log(IStatus.WARNING, error); } @Override public void warning(SAXParseException error) throws SAXException { log(IStatus.WARNING, error); } public void log(int code, Throwable error) { log(code, error.getMessage(), error); } public void log(int code, String errorMessage, Throwable error) { problems.add(new Status(code, BeansCorePlugin.PLUGIN_ID, IResourceStatus.FAILED_READ_METADATA, errorMessage, error)); } }