Coverage Report - org.argouml.model.euml.XmiReaderEUMLImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
XmiReaderEUMLImpl
0%
0/108
0%
0/64
4.846
 
 1  
 // $Id: XmiReaderEUMLImpl.java 18239 2010-04-12 06:51:13Z tfmorris $
 2  
 /*******************************************************************************
 3  
  * Copyright (c) 2007,2010 Tom Morris and other contributors
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    Tom Morris - initial implementation
 11  
  *    Bogdan Pistol - undo support & UUID maps for diagrams
 12  
  *    thn
 13  
  *****************************************************************************/
 14  
 
 15  
 package org.argouml.model.euml;
 16  
 
 17  
 import java.io.BufferedInputStream;
 18  
 import java.io.IOException;
 19  
 import java.io.InputStream;
 20  
 import java.net.MalformedURLException;
 21  
 import java.net.URL;
 22  
 import java.util.ArrayList;
 23  
 import java.util.Collection;
 24  
 import java.util.HashMap;
 25  
 import java.util.HashSet;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 import java.util.Set;
 30  
 
 31  
 import org.apache.log4j.Logger;
 32  
 import org.argouml.model.NotImplementedException;
 33  
 import org.argouml.model.UmlException;
 34  
 import org.argouml.model.XmiReader;
 35  
 import org.eclipse.emf.common.util.URI;
 36  
 import org.eclipse.emf.ecore.EObject;
 37  
 import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl.BasicFeatureMapEntry;
 38  
 import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl.SimpleFeatureMapEntry;
 39  
 import org.eclipse.emf.ecore.resource.Resource;
 40  
 import org.eclipse.emf.ecore.util.FeatureMap.Entry;
 41  
 import org.eclipse.emf.ecore.xml.type.AnyType;
 42  
 import org.eclipse.uml2.uml.Element;
 43  
 import org.xml.sax.InputSource;
 44  
 
 45  
 /**
 46  
  * The implementation of the XmiReader for EUML2.
 47  
  */
 48  
 class XmiReaderEUMLImpl implements XmiReader {
 49  
     
 50  0
     private static final Logger LOG = Logger.getLogger(XmiReaderEUMLImpl.class);
 51  
 
 52  
     /**
 53  
      * The model implementation.
 54  
      */
 55  
     private EUMLModelImplementation modelImpl;
 56  
     
 57  0
     private static Set<String> searchDirs = new HashSet<String>();
 58  
     
 59  
     private Resource resource;
 60  
 
 61  
     /**
 62  
      * Constructor.
 63  
      * 
 64  
      * @param implementation
 65  
      *            The ModelImplementation.
 66  
      */
 67  0
     public XmiReaderEUMLImpl(EUMLModelImplementation implementation) {
 68  0
         modelImpl = implementation;
 69  0
     }
 70  
 
 71  
     public int getIgnoredElementCount() {
 72  0
         return 0;
 73  
     }
 74  
 
 75  
     public String[] getIgnoredElements() {
 76  
         // Not needed currently for UML 2
 77  0
         return new String[0];
 78  
     }
 79  
 
 80  
     public Map<String, Object> getXMIUUIDToObjectMap() {
 81  0
         if (resource == null) {
 82  0
             throw new IllegalStateException();
 83  
         }
 84  0
         Map<String, Object> map = new HashMap<String, Object>();
 85  0
         Iterator<EObject> it = resource.getAllContents();
 86  0
         while (it.hasNext()) {
 87  0
             EObject o  = it.next();
 88  0
             map.put(resource.getURIFragment(o), o);
 89  0
         }
 90  0
         return map;
 91  
     }
 92  
 
 93  
 
 94  
     public Collection parse(InputSource inputSource, boolean readOnly)
 95  
         throws UmlException {
 96  
         
 97  0
         if (inputSource == null) {
 98  0
             throw new NullPointerException(
 99  
                     "The input source must be non-null."); //$NON-NLS-1$
 100  
         }
 101  0
         InputStream is = null;
 102  0
         boolean needsClosing = false;
 103  0
         String name = inputSource.getSystemId();
 104  0
         if (name == null) {
 105  0
             name = inputSource.getPublicId();
 106  
         }
 107  0
         if (name == null) {
 108  0
             name = inputSource.toString();
 109  
         }
 110  0
         LOG.debug("Parsing " + name); //$NON-NLS-1$
 111  0
         if (inputSource.getByteStream() != null) {
 112  0
             is = inputSource.getByteStream();
 113  0
         } else if (inputSource.getSystemId() != null) {
 114  
             try {
 115  0
                 URL url = new URL(inputSource.getSystemId());
 116  0
                 if (url != null) {
 117  0
                     LOG.debug("Parsing URL " + url); //$NON-NLS-1$
 118  0
                     is = url.openStream();
 119  0
                     if (is != null) {
 120  0
                         is = new BufferedInputStream(is);
 121  0
                         needsClosing = true;
 122  
                     }
 123  
                 }
 124  0
             } catch (MalformedURLException e) {
 125  
                 // do nothing
 126  0
             } catch (IOException e) {
 127  
                 // do nothing
 128  0
             }
 129  
 
 130  
         }
 131  0
         if (is == null) {
 132  0
             throw new UnsupportedOperationException();
 133  
         }
 134  
 
 135  
         // TODO: Review - priority of public ID vs system ID has been reversed
 136  
         // from original implementation
 137  0
         String id = inputSource.getPublicId();
 138  0
         if (id == null) {
 139  0
             id = inputSource.getSystemId();
 140  0
             if (id != null) {
 141  
                 // we only take the filename, not the whole system path
 142  0
                 int ix = id.lastIndexOf('/');
 143  0
                 if (ix != -1) {
 144  0
                     id = id.substring(ix + 1);
 145  
                 }
 146  
             }
 147  
         }
 148  
 
 149  0
         Resource r = UMLUtil.getResource(modelImpl, 
 150  
                 URI.createURI(id), readOnly);
 151  
         
 152  
         try {
 153  0
             modelImpl.getModelEventPump().stopPumpingEvents();
 154  0
             r.unload();
 155  0
             r.load(is, null);
 156  
             // TODO: Some import-only UML 2 profiles trigger this - Investigate.
 157  
 //            if (!isUML2(r)) {
 158  
 //                throw new UmlException("Attempted to load non-UML 2.x file");
 159  
 //            }
 160  0
             if (isUML14(r)) {
 161  0
                 throw new UmlException("Attempted to load UML 1.4 file"); //$NON-NLS-1$
 162  
             }
 163  0
         } catch (IOException e) {
 164  0
             throw new UmlException(e);
 165  
         } finally {
 166  0
             modelImpl.getModelEventPump().startPumpingEvents();
 167  0
             if (needsClosing) {
 168  
                 try {
 169  0
                     is.close();
 170  0
                 } catch (IOException e) {
 171  0
                     throw new RuntimeException(e);
 172  0
                 }
 173  
             }
 174  
         }
 175  0
         resource = r;
 176  0
         LOG.debug("Parsed resource " + resource  //$NON-NLS-1$
 177  
                 + " with " + resource.getContents().size() + " elements"); //$NON-NLS-1$ //$NON-NLS-2$
 178  0
         return r.getContents();
 179  
     }
 180  
 
 181  
     /**
 182  
      * Test whether this is a UML2 file. Returns as soon as the first UML2
 183  
      * element is seen.
 184  
      * 
 185  
      * @param r resource containing loaded UML model
 186  
      * @return true if any of the contained objects are instances of UML2
 187  
      *         Element.
 188  
      */
 189  
     private boolean isUML2(Resource r) {
 190  0
         for (EObject eobj: r.getContents()) {
 191  0
             if (eobj instanceof Element) {
 192  0
                 return true;
 193  
             }
 194  
         }
 195  0
         return false;
 196  
     }
 197  
     
 198  
     /**
 199  
      * Attempt to detect ArgoUML/NetBeans MDR style UML 1.4 XMI files. These can
 200  
      * be loaded without complaint by EMF, but they won't do us any good.
 201  
      * 
 202  
      * @param r resource containing the loaded file
 203  
      * @return true if XMI.header/XMI.metamodel contains xmi.name="UML" and
 204  
      *         xmi.version="1.4"
 205  
      */
 206  
     private boolean isUML14(Resource r) {
 207  0
         for (EObject eobj : r.getContents()) {
 208  0
             if ("XMI.header".equals(eobj.eClass().getName())) { //$NON-NLS-1$
 209  0
                 for (Entry e1 : ((AnyType) eobj).getMixed()) {
 210  0
                     if (e1 instanceof BasicFeatureMapEntry) {
 211  0
                         BasicFeatureMapEntry x1 = (BasicFeatureMapEntry) e1;
 212  0
                         String n1 = x1.getEStructuralFeature().getName();
 213  0
                         if ("XMI.metamodel".equals(n1)) { //$NON-NLS-1$
 214  0
                             AnyType v = (AnyType) x1.getValue();
 215  0
                             for (Entry e2 : v.getAnyAttribute()) {
 216  0
                                 if (e2 instanceof SimpleFeatureMapEntry) {
 217  0
                                     SimpleFeatureMapEntry x = (SimpleFeatureMapEntry) e2;
 218  0
                                     String n = x.getEStructuralFeature().getName();
 219  0
                                     if ("xmi.name".equals(n)) { //$NON-NLS-1$
 220  0
                                         if (!("UML".equals((String) x.getValue()))) { //$NON-NLS-1$
 221  0
                                             LOG.warn("Tried to parse XMI file with "
 222  
                                                             + "XMI.header/XMI.metamodel/xmi.name = "
 223  
                                                             + (String) x.getValue());
 224  0
                                             return false;
 225  
                                         }
 226  0
                                     } else if ("xmi.version".equals(n)) { //$NON-NLS-1$
 227  0
                                         String version = (String) x.getValue();
 228  0
                                         if (version != null
 229  
                                                 && version.startsWith("1.4")) { //$NON-NLS-1$
 230  0
                                             LOG.debug("Tried to parse XMI file with "
 231  
                                                     + "XMI.header/XMI.metamodel/xmi.version = "
 232  
                                                     + version);
 233  0
                                             return true;
 234  
                                         }
 235  
                                     }
 236  0
                                 }
 237  
                             }
 238  
                         }
 239  0
                     }
 240  
                 }
 241  
             }
 242  
         }
 243  0
         return false;
 244  
     }
 245  
 
 246  
     public boolean setIgnoredElements(String[] elementNames) {
 247  0
         if (elementNames == null) {
 248  0
             return true;
 249  
         }
 250  0
         throw new NotImplementedException("setIgnoredElements not implemented for UML 2.x");
 251  
         // TODO: Silently ignore instead?
 252  
 //        return false;
 253  
     }
 254  
 
 255  
     public String getTagName() {
 256  0
         if (resource == null) {
 257  0
             return "uml:Model"; //$NON-NLS-1$
 258  
         }
 259  0
         List l = resource.getContents();
 260  0
         if (!l.isEmpty()) {
 261  0
             return "uml:" //$NON-NLS-1$
 262  
                     + modelImpl.getMetaTypes().getName(l.get(0)); 
 263  
         } else {
 264  0
             return null;
 265  
         }
 266  
     }
 267  
 
 268  
     public void addSearchPath(String path) {
 269  0
         searchDirs.add(path);
 270  0
     }
 271  
 
 272  
     public List<String> getSearchPath() {
 273  0
         return new ArrayList<String>(searchDirs);
 274  
     }
 275  
 
 276  
     public void removeSearchPath(String path) {
 277  0
         searchDirs.remove(path);
 278  0
     }
 279  
 
 280  
     public String getHeader() {
 281  
         // TODO: Auto-generated method stub
 282  0
         throw new NotYetImplementedException();
 283  
     }
 284  
     
 285  
 }