Package de.itemis.tooling.xturtle.resource

Source Code of de.itemis.tooling.xturtle.resource.TurtleResourceIndex

/*******************************************************************************
* Copyright (c) 2013 AKSW Xturtle Project, itemis AG (http://www.itemis.eu).
* 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
******************************************************************************/
package de.itemis.tooling.xturtle.resource;

import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;

import com.google.common.base.Optional;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

import de.itemis.tooling.xturtle.xturtle.Base;
import de.itemis.tooling.xturtle.xturtle.PrefixId;
import de.itemis.tooling.xturtle.xturtle.QNameDef;
import de.itemis.tooling.xturtle.xturtle.QNameRef;
import de.itemis.tooling.xturtle.xturtle.UriDef;
import de.itemis.tooling.xturtle.xturtle.UriRef;
import de.itemis.tooling.xturtle.xturtle.XturtlePackage;

//THE central class for most of the turtle functionality, as it attaches a resolved URI to
//each Resource(Reference). Otherwise handling the model would become even more messy.
//this is done via an Adapter stored in the model root which holds maps with all the
//necessary information
//TODO clean up this code, extract services
class TurtleResourceIndex implements Adapter {

  public void notifyChanged(Notification notification) {
  }

  public Notifier getTarget() {
    return null;
  }

  public void setTarget(Notifier newTarget) {
  }

  public boolean isAdapterForType(Object type) {
    return false;
  }

  private BiMap<EObject,String> fragmentMap;
  private URI currentBaseUri;
  private Map<String, String> prefixToUriMap;
  private Map<EObject,QualifiedName> qNameMap;

  String getFragment(EObject o){
    return fragmentMap.get(o);
  }

  EObject getObject(String fragment){
    return fragmentMap.inverse().get(fragment);
  }
 
  QualifiedName getName(EObject object){
    return qNameMap.get(object);
  }

    void initIndex(EObject root){
      resetMaps(root.eResource());
    int i=0;
    addFragmentEntry(i++, root);
    TreeIterator<EObject> iterator = root.eAllContents();
    while(iterator.hasNext()) {
      EObject obj = iterator.next();
      addFragmentEntry(i++, obj);
      addUriAndNameEntries(obj);
    }
  }

  private URI getNormalizedUri(String uriString){
    try {
      return URI.create(uriString).normalize();
    } catch (Exception e) {
      return null;
    }
  }
 
  private void addUriAndNameEntries(EObject obj) {
    if(obj instanceof PrefixId){
      addPrefixIdEntries((PrefixId) obj);
    } else if(obj instanceof Base){
      addBaseEntries((Base) obj);
    } else if(obj instanceof QNameDef){
      String prefix=getPrefixText(obj,XturtlePackage.Literals.QNAME_DEF__PREFIX);
      String prefixUri = prefixToUriMap.get(prefix);
      if(prefixUri!=null){
        qNameMap.put(obj, QualifiedName.create(prefixUri, Optional.fromNullable(((QNameDef) obj).getId()).or("")));
      }
    } else if(obj instanceof UriDef){
      QualifiedName qName=resolve(currentBaseUri, ((UriDef) obj).getUri());
      if(qName!=null){
        qNameMap.put(obj, qName);
      }
    } else if(obj instanceof QNameRef){
      String prefix=getPrefixText(obj, XturtlePackage.Literals.QNAME_REF__PREFIX);
      List<INode> refNodes = NodeModelUtils.findNodesForFeature(obj, XturtlePackage.Literals.RESOURCE_REF__REF);
      String ref=NodeModelUtils.getTokenText(refNodes.get(0));
      if(ref!=null&& ref.length()>0&& ref.charAt(0)==':'){
        String nsUri=prefixToUriMap.get(prefix);
        if(nsUri!=null){
          qNameMap.put(obj, QualifiedName.create(nsUri, ref.substring(1)));
        }
      }

    } else if(obj instanceof UriRef){
      QualifiedName qName;
      List<INode> refNodes = NodeModelUtils.findNodesForFeature(obj, XturtlePackage.Literals.RESOURCE_REF__REF);
      if(refNodes.size()==1){
        String ref = refNodes.get(0).getText();
        ref=ref.substring(1, ref.length()-1);
        qName=resolve(currentBaseUri, ref);
        qNameMap.put(obj, qName);
      }
//      else{
//        qNameMap.put(obj, QualifiedName.create("invalid","invalid"));
//      }
   
  }

  private String getPrefixText(EObject obj, EReference ref) {
    String prefix=null;
    List<INode> nodes = NodeModelUtils.findNodesForFeature(obj, ref);
    switch(nodes.size()){
      case 0:
        prefix="";
        break;
      case 1:
        prefix=NodeModelUtils.getTokenText(nodes.get(0));
        break;
    }
    return prefix;
  }

  private void addBaseEntries(Base obj) {
    URI uri=getNormalizedUri(obj.getUri());
    if(uri!=null){
      if(uri.isAbsolute()){
        currentBaseUri=uri;
      }else{
        currentBaseUri=currentBaseUri.resolve(uri).normalize();
      }
      qNameMap.put(obj, QualifiedName.create(currentBaseUri.toString()));
    }
  }

  private void addPrefixIdEntries(PrefixId obj) {
    String prefix = Optional.fromNullable(obj.getId()).or("");
    String uriString=obj.getUri();
    URI uri=getNormalizedUri(uriString);
    if(uri!=null){
      if (uri.isAbsolute()){
        prefixToUriMap.put(prefix, uriString);
      }else{
        prefixToUriMap.put(prefix,currentBaseUri.resolve(uri).normalize().toString());
      }
      qNameMap.put(obj, QualifiedName.create(prefixToUriMap.get(prefix)));
    }
  }
  //TODO in externe Komponente auslagern, testen
  private QualifiedName resolve(URI base, String uriAsString) {
    String namespace;
    String name;
    //from baseUri alone
    if(uriAsString==null || uriAsString.length()==0){
      String fragment=base.getFragment();
      String baseAsString=base.toString();
      if(fragment!=null){
        name=fragment;
        namespace=baseAsString.substring(0, baseAsString.lastIndexOf('#')+1);
      }else{
        int lastSlash = baseAsString.lastIndexOf('/');
        name=baseAsString.substring(lastSlash+1);
        namespace=baseAsString.substring(0,lastSlash+1);
      }
    }else{
      URI uri = getNormalizedUri(uriAsString);
      if(uri==null){
        return null;
      }else if(uri.isAbsolute()){
        return resolve(uri,null);
      }else if(base.getFragment()!=null){
        if(uriAsString.indexOf('/')>=0){
          namespace="invalid";
          name="invalid";
        }else{
          //we assume that the fragment is empty as nothing else makes sense for the base uri
          namespace=base.toString();
          name=uriAsString;
        }
      }else{
        return resolve(base.resolve(uriAsString).normalize(),null);
      }
    }
    return QualifiedName.create(namespace,name);
  }

  private void resetMaps(Resource resource){
    fragmentMap=HashBiMap.create();
    prefixToUriMap=new HashMap<String, String>();
    qNameMap=new HashMap<EObject, QualifiedName>();
    StringBuilder b=new StringBuilder("file:///");
    b.append(resource.getURI().lastSegment());
    currentBaseUri=URI.create(b.toString());
  }

  private void addFragmentEntry(int index, EObject object){
    fragmentMap.put(object, ""+index);
  }


}
TOP

Related Classes of de.itemis.tooling.xturtle.resource.TurtleResourceIndex

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.