/* $Id: ArgoParser.java 17832 2010-01-12 19:02:29Z linus $ ***************************************************************************** * Copyright (c) 2009 Contributors - see below * 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: * tfmorris ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 1996-2008 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.persistence; import java.io.Reader; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.argouml.kernel.Project; import org.argouml.kernel.ProjectSettings; import org.argouml.notation.NotationSettings; import org.argouml.uml.diagram.DiagramSettings; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * Parser for ArgoUML project description file (.argo) */ class ArgoParser extends SAXParserBase { /** * Logger. */ private static final Logger LOG = Logger.getLogger(ArgoParser.class); private Project project; private ProjectSettings ps; private DiagramSettings diagramDefaults; private NotationSettings notationSettings; private ArgoTokenTable tokens = new ArgoTokenTable(); private List<String> memberList = new ArrayList<String>(); /** * The constructor. * */ public ArgoParser() { super(); } /** * @param theProject the project to populate * @param source the input source * @throws SAXException on error when parsing xml */ public void readProject(Project theProject, InputSource source) throws SAXException { if (source == null) { throw new IllegalArgumentException( "An InputSource must be supplied"); } preRead(theProject); try { parse(source); } catch (SAXException e) { logError(source.toString(), e); throw e; } } /** * @param theProject the project to populate * @param reader the reader * @throws SAXException on error when parsing xml */ public void readProject(Project theProject, Reader reader) throws SAXException { if (reader == null) { throw new IllegalArgumentException( "A reader must be supplied"); } preRead(theProject); try { parse(reader); } catch (SAXException e) { logError(reader.toString(), e); throw e; } } private void preRead(Project theProject) { LOG.info("======================================="); LOG.info("== READING PROJECT " + theProject); project = theProject; ps = project.getProjectSettings(); diagramDefaults = ps.getDefaultDiagramSettings(); notationSettings = ps.getNotationSettings(); } private void logError(String projectName, SAXException e) { LOG.error("Exception reading project================", e); LOG.error(projectName); } /** * Get the project to which the URI is to be parsed. * @return the project */ public Project getProject() { return project; } /** * Set the project to which the URI is to be parsed. * @param newProj the project */ public void setProject(Project newProj) { project = newProj; ps = project.getProjectSettings(); } /* * @see org.argouml.persistence.SAXParserBase#handleStartElement( * org.argouml.persistence.XMLElement) */ public void handleStartElement(XMLElement e) throws SAXException { if (DBG) { LOG.debug("NOTE: ArgoParser handleStartTag:" + e.getName()); } switch (tokens.toToken(e.getName(), true)) { case ArgoTokenTable.TOKEN_ARGO: handleArgo(e); break; case ArgoTokenTable.TOKEN_DOCUMENTATION: handleDocumentation(e); break; case ArgoTokenTable.TOKEN_SETTINGS: handleSettings(e); break; default: if (DBG) { LOG.warn("WARNING: unknown tag:" + e.getName()); } break; } } /* * @see org.argouml.persistence.SAXParserBase#handleEndElement( * org.argouml.persistence.XMLElement) */ @SuppressWarnings("deprecation") public void handleEndElement(XMLElement e) throws SAXException { if (DBG) { LOG.debug("NOTE: ArgoParser handleEndTag:" + e.getName() + "."); } switch (tokens.toToken(e.getName(), false)) { case ArgoTokenTable.TOKEN_MEMBER: handleMember(e); break; case ArgoTokenTable.TOKEN_AUTHORNAME: handleAuthorName(e); break; case ArgoTokenTable.TOKEN_AUTHOREMAIL: handleAuthorEmail(e); break; case ArgoTokenTable.TOKEN_VERSION: handleVersion(e); break; case ArgoTokenTable.TOKEN_DESCRIPTION: handleDescription(e); break; case ArgoTokenTable.TOKEN_SEARCHPATH: handleSearchpath(e); break; case ArgoTokenTable.TOKEN_HISTORYFILE: handleHistoryfile(e); break; case ArgoTokenTable.TOKEN_NOTATIONLANGUAGE: handleNotationLanguage(e); break; case ArgoTokenTable.TOKEN_SHOWBOLDNAMES: handleShowBoldNames(e); break; case ArgoTokenTable.TOKEN_USEGUILLEMOTS: handleUseGuillemots(e); break; case ArgoTokenTable.TOKEN_SHOWVISIBILITY: handleShowVisibility(e); break; case ArgoTokenTable.TOKEN_SHOWMULTIPLICITY: handleShowMultiplicity(e); break; case ArgoTokenTable.TOKEN_SHOWINITIALVALUE: handleShowInitialValue(e); break; case ArgoTokenTable.TOKEN_SHOWPROPERTIES: handleShowProperties(e); break; case ArgoTokenTable.TOKEN_SHOWTYPES: handleShowTypes(e); break; case ArgoTokenTable.TOKEN_SHOWSTEREOTYPES: handleShowStereotypes(e); break; case ArgoTokenTable.TOKEN_SHOWSINGULARMULTIPLICITIES: handleShowSingularMultiplicities(e); break; case ArgoTokenTable.TOKEN_DEFAULTSHADOWWIDTH: handleDefaultShadowWidth(e); break; case ArgoTokenTable.TOKEN_FONTNAME: handleFontName(e); break; case ArgoTokenTable.TOKEN_FONTSIZE: handleFontSize(e); break; case ArgoTokenTable.TOKEN_GENERATION_OUTPUT_DIR: // ignored - it shouldn't have been in the project in the 1st place break; case ArgoTokenTable.TOKEN_SHOWASSOCIATIONNAMES: handleShowAssociationNames(e); break; case ArgoTokenTable.TOKEN_HIDEBIDIRECTIONALARROWS: handleHideBidirectionalArrows(e); break; case ArgoTokenTable.TOKEN_ACTIVE_DIAGRAM: handleActiveDiagram(e); break; default: if (DBG) { LOG.warn("WARNING: unknown end tag:" + e.getName()); } break; } } /* * @see org.argouml.persistence.SAXParserBase#isElementOfInterest(String) */ @Override protected boolean isElementOfInterest(String name) { return tokens.contains(name); } /** * @param e the element */ protected void handleArgo(@SuppressWarnings("unused") XMLElement e) { /* do nothing */ } /** * @param e the element */ protected void handleDocumentation( @SuppressWarnings("unused") XMLElement e) { /* do nothing */ } /** * @param e the element */ protected void handleSettings(@SuppressWarnings("unused") XMLElement e) { /* do nothing */ } /** * @param e the element */ protected void handleAuthorName(XMLElement e) { String authorname = e.getText().trim(); project.setAuthorname(authorname); } /** * @param e the element */ protected void handleAuthorEmail(XMLElement e) { String authoremail = e.getText().trim(); project.setAuthoremail(authoremail); } /** * @param e the element */ protected void handleVersion(XMLElement e) { String version = e.getText().trim(); project.setVersion(version); } /** * @param e the element */ protected void handleDescription(XMLElement e) { String description = e.getText().trim(); project.setDescription(description); } /** * @param e the element */ protected void handleSearchpath(XMLElement e) { String searchpath = e.getAttribute("href").trim(); project.addSearchPath(searchpath); } /** * @param e the element * @throws SAXException on any error parsing the member XML. */ protected void handleMember(XMLElement e) throws SAXException { if (e == null) { throw new SAXException("XML element is null"); } String type = e.getAttribute("type"); memberList.add(type); } /** * @param e the element */ protected void handleHistoryfile(XMLElement e) { if (e.getAttribute("name") == null) { return; } String historyfile = e.getAttribute("name").trim(); project.setHistoryFile(historyfile); } /** * @param e the element */ protected void handleNotationLanguage(XMLElement e) { String language = e.getText().trim(); boolean success = ps.setNotationLanguage(language); /* TODO: Here we should e.g. show the user a message that * the loaded project was using a Notation that is not * currently available and a fall back on the default Notation * was done. Maybe this can be implemented in the * PersistenceManager? */ } /** * @param e the element */ protected void handleShowBoldNames(XMLElement e) { String ug = e.getText().trim(); diagramDefaults.setShowBoldNames(Boolean.parseBoolean(ug)); } /** * @param e the element */ protected void handleUseGuillemots(XMLElement e) { String ug = e.getText().trim(); ps.setUseGuillemots(ug); } /** * @param e the element */ protected void handleShowVisibility(XMLElement e) { String showVisibility = e.getText().trim(); notationSettings.setShowVisibilities( Boolean.parseBoolean(showVisibility)); } /** * @param e the element */ protected void handleShowMultiplicity(XMLElement e) { String showMultiplicity = e.getText().trim(); notationSettings.setShowMultiplicities( Boolean.parseBoolean(showMultiplicity)); } /** * @param e the element */ protected void handleShowInitialValue(XMLElement e) { String showInitialValue = e.getText().trim(); notationSettings.setShowInitialValues( Boolean.parseBoolean(showInitialValue)); } /** * @param e the element */ protected void handleShowProperties(XMLElement e) { String showproperties = e.getText().trim(); notationSettings.setShowProperties( Boolean.parseBoolean(showproperties)); } /** * @param e the element */ protected void handleShowTypes(XMLElement e) { String showTypes = e.getText().trim(); notationSettings.setShowTypes(Boolean.parseBoolean(showTypes)); } /** * @param e the element */ protected void handleShowStereotypes(XMLElement e) { String showStereotypes = e.getText().trim(); ps.setShowStereotypes(Boolean.parseBoolean(showStereotypes)); } /** * @param e the element */ protected void handleShowSingularMultiplicities(XMLElement e) { String showSingularMultiplicities = e.getText().trim(); notationSettings.setShowSingularMultiplicities( Boolean.parseBoolean(showSingularMultiplicities)); } /** * @param e the element */ protected void handleDefaultShadowWidth(XMLElement e) { String dsw = e.getText().trim(); diagramDefaults.setDefaultShadowWidth(Integer.parseInt(dsw)); } /** * @param e the element */ protected void handleFontName(XMLElement e) { String dsw = e.getText().trim(); diagramDefaults.setFontName(dsw); } /** * @param e the element */ protected void handleFontSize(XMLElement e) { String dsw = e.getText().trim(); try { diagramDefaults.setFontSize(Integer.parseInt(dsw)); } catch (NumberFormatException e1) { LOG.error("NumberFormatException while parsing Font Size", e1); } } /** * @param e the element */ protected void handleShowAssociationNames(XMLElement e) { String showAssociationNames = e.getText().trim(); notationSettings.setShowAssociationNames( Boolean.parseBoolean(showAssociationNames)); } /** * @param e the element */ protected void handleHideBidirectionalArrows(XMLElement e) { String hideBidirectionalArrows = e.getText().trim(); // NOTE: For historical reasons true == hide, so we need to invert // the sense of this diagramDefaults.setShowBidirectionalArrows(! Boolean.parseBoolean(hideBidirectionalArrows)); } protected void handleActiveDiagram(XMLElement e) { /* At this stage during loading, the diagrams are * not created yet - so we have to store this name for later use. */ project.setSavedDiagramName(e.getText().trim()); } /** * Get the number of diagram members read. * @return the number of diagram members read. */ public List<String> getMemberList() { return memberList; } }