Package com.puppetlabs.geppetto.pp.dsl.ui.editor.hover

Source Code of com.puppetlabs.geppetto.pp.dsl.ui.editor.hover.PPDocumentationProvider

/**
* Copyright (c) 2013 Puppet Labs, Inc. and other contributors, as listed 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:
*   Puppet Labs
*/
package com.puppetlabs.geppetto.pp.dsl.ui.editor.hover;

import java.util.Collections;
import java.util.List;

import com.puppetlabs.geppetto.pp.Definition;
import com.puppetlabs.geppetto.pp.HostClassDefinition;
import com.puppetlabs.geppetto.pp.NodeDefinition;
import com.puppetlabs.geppetto.pp.VerbatimTE;
import com.puppetlabs.geppetto.pp.dsl.adapters.CrossReferenceAdapter;
import com.puppetlabs.geppetto.pp.dsl.adapters.ResourceDocumentationAdapter;
import com.puppetlabs.geppetto.pp.dsl.adapters.ResourceDocumentationAdapterFactory;
import com.puppetlabs.geppetto.pp.dsl.formatting.PPCommentConfiguration;
import com.puppetlabs.geppetto.pp.dsl.services.PPGrammarAccess;
import com.puppetlabs.geppetto.pp.dsl.ui.labeling.PPDescriptionLabelProvider;
import com.puppetlabs.geppetto.pp.dsl.ui.labeling.PPLabelProvider;
import com.puppetlabs.geppetto.pp.pptp.IDocumented;
import com.puppetlabs.geppetto.ruby.RubyDocProcessor;
import com.puppetlabs.xtext.dommodel.formatter.comments.CommentProcessor;
import com.puppetlabs.xtext.dommodel.formatter.comments.CommentProcessor.CommentText;
import com.puppetlabs.xtext.dommodel.formatter.comments.ICommentConfiguration.CommentType;
import com.puppetlabs.xtext.dommodel.formatter.comments.ICommentContainerInformation;
import com.puppetlabs.xtext.textflow.CharSequences;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.swt.graphics.Image;
import org.eclipse.xtext.documentation.IEObjectDocumentationProvider;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.util.PolymorphicDispatcher;

import com.google.inject.Inject;

/**
* Provider of documentation for PP semantic objects/references.
*
*/
public class PPDocumentationProvider implements IEObjectDocumentationProvider {

  private PolymorphicDispatcher<String> documentationDispatcher = new PolymorphicDispatcher<String>(
    "_document", 1, 2, Collections.singletonList(this), PolymorphicDispatcher.NullErrorHandler.<String> get()) {
    @Override
    protected String handleNoSuchMethod(Object... params) {
      return null;
    }
  };

  private PolymorphicDispatcher<Image> imageDispatcher = new PolymorphicDispatcher<Image>(
    "_image", 1, 2, Collections.singletonList(this), PolymorphicDispatcher.NullErrorHandler.<Image> get()) {
    @Override
    protected Image handleNoSuchMethod(Object... params) {
      return null;
    }
  };

  private PolymorphicDispatcher<String> labelDispatcher = new PolymorphicDispatcher<String>(
    "_label", 1, 2, Collections.singletonList(this), PolymorphicDispatcher.NullErrorHandler.<String> get()) {
    @Override
    protected String handleNoSuchMethod(Object... params) {
      return null;
    }
  };

  private PolymorphicDispatcher<IEObjectDescription> xrefDispatcher = new PolymorphicDispatcher<IEObjectDescription>(
    "_xref", 1, 1, Collections.singletonList(this),
    PolymorphicDispatcher.NullErrorHandler.<IEObjectDescription> get()) {
    @Override
    protected IEObjectDescription handleNoSuchMethod(Object... params) {
      return null;
    }
  };

  @Inject
  protected PPDescriptionLabelProvider descriptionLabelProvider;

  @Inject
  protected PPLabelProvider labelProvider;

  // protected String _document(AttributeOperation o) {
  // return getCrossReferenceDocumentation(o);
  // }

  @Inject
  PPCommentConfiguration commentConfiguration;

  @Inject
  PPGrammarAccess ga;

  protected String _document(Definition o) {
    return getPPDocumentation(o);
  }

  /**
   * Get cross reference for all types of Expressions
   *
   * @param o
   * @return
   */
  protected String _document(EObject o) {
    return getCrossReferenceDocumentation(o);
  }

  protected String _document(HostClassDefinition o) {
    return getPPDocumentation(o);
  }

  /**
   * All PPTP things with documentation are instances of IDocumented
   *
   * @param o
   * @return
   */
  protected String _document(IDocumented o) {
    // produces a string, get it as HTML documentation if not already in HTML
    return document(o.getDocumentation());
  }

  protected String _document(NodeDefinition o) {
    return getPPDocumentation(o);
  }

  protected String _document(Object o) {
    return null;
  }

  protected String _document(String o) {
    if(o.startsWith("<"))
      return o;
    // turn puppet internal doc format (from Ruby) into HTML
    StringBuilder builder = new StringBuilder();
    builder.append("<p>");
    builder.append(o);
    builder.append("</p>");
    return builder.toString();
  }

  protected String _document(VerbatimTE o) {
    // is only possible when it is in a string (eContainer()) that is a reference.
    return getCrossReferenceDocumentation(o.eContainer());
  }

  protected Image _image(EObject o) {
    Image result = getCrossReferenceImage(o);
    if(result == null)
      result = getPPImage(o);
    return result;

  }

  protected Image _image(VerbatimTE o) {
    // is only possible when it is in a string (eContainer()) that is a reference.
    return getCrossReferenceImage(o.eContainer());
  }

  protected String _label(EObject o) {
    return getCrossReferenceLabel(o);
  }

  protected String _label(VerbatimTE o) {
    // is only possible when it is in a string (eContainer()) that is a reference.
    return getCrossReferenceLabel(o.eContainer());
  }

  protected IEObjectDescription _xref(EObject o) {
    return getCrossReference(o);
  }

  protected IEObjectDescription _xref(VerbatimTE o) {
    return getCrossReference(o.eContainer());
  }

  public String document(Object o) {
    if(o == null)
      return null;
    String result = documentationDispatcher.invoke(o);
    return result == null && o instanceof EObject
        ? documentationDispatcher.invoke(((EObject) o).eContainingFeature(), o)
        : result;
  }

  private IEObjectDescription getCrossReference(EObject o) {
    List<IEObjectDescription> xrefs = CrossReferenceAdapter.get(o);
    if(xrefs == null)
      return null;
    if(xrefs.size() == 1)
      return xrefs.get(0);
    return null;
  }

  private String getCrossReferenceDocumentation(EObject o) {
    List<IEObjectDescription> xrefs = CrossReferenceAdapter.get(o);
    if(xrefs == null)
      return null;
    if(xrefs.size() > 1) {
      return "Ambiguous reference";
    }
    if(xrefs.size() == 0) {
      return "Unresolved";
    }
    IEObjectDescription ref = xrefs.get(0);

    EObject x = ref.getEObjectOrProxy();
    if(x.eIsProxy())
      x = EcoreUtil.resolve(x, o);
    return document(x);

  }

  private Image getCrossReferenceImage(EObject o) {
    List<IEObjectDescription> xrefs = CrossReferenceAdapter.get(o);
    if(xrefs == null)
      return null;
    if(xrefs.size() > 1) {
      return null;
    }
    if(xrefs.size() == 0) {
      return null;
    }
    IEObjectDescription ref = xrefs.get(0);
    return descriptionLabelProvider.getImage(ref);
  }

  private String getCrossReferenceLabel(EObject o) {
    List<IEObjectDescription> xrefs = CrossReferenceAdapter.get(o);
    if(xrefs == null)
      return null;
    if(xrefs.size() > 1) {
      return null;
    }
    if(xrefs.size() == 0) {
      return null;
    }
    IEObjectDescription ref = xrefs.get(0);
    return descriptionLabelProvider.getText(ref);

  }

  /**
   * Returns the documentation associated with the object referenced by the given EObject.
   */
  @Override
  public String getDocumentation(EObject o) {
    return document(o);
  }

  /**
   * Returns an image for the objct referenced by the given EObject
   *
   * @param o
   * @return
   */
  public Image getImage(Object o) {
    if(o == null)
      return null;
    Image result = imageDispatcher.invoke(o);
    return result == null && o instanceof EObject
        ? imageDispatcher.invoke(((EObject) o).eContainingFeature(), o)
        : result;

  }

  /**
   * @param o
   * @return
   */
  private String getPPDocumentation(EObject o) {
    ResourceDocumentationAdapter adapter = ResourceDocumentationAdapterFactory.eINSTANCE.adapt(o.eResource());
    List<INode> nodes = adapter.get(o);
    if(nodes != null && nodes.size() > 0) {
      // rip text from the nodes
      CharSequence result = CharSequences.empty();
      for(INode n : nodes)
        result = CharSequences.concatenate(result, n.getText());

      ICommentContainerInformation in = (nodes.size() == 1 && nodes.get(0).getGrammarElement() == ga.getML_COMMENTRule())
          ? commentConfiguration.getContainerInformation(CommentType.Multiline)
          : (commentConfiguration.getContainerInformation(CommentType.SingleLine));

      CommentProcessor cpr = new CommentProcessor();
      CommentText comment = cpr.separateCommentFromContainer(result, in, "\n"); // TODO: cheating on line separator
      return new RubyDocProcessor().asHTML(comment.getLines());

    }
    return null;
  }

  private Image getPPImage(EObject o) {
    return labelProvider.getImage(o);
  }

  /**
   * Returns a text label for the object referenced by the given Object.
   *
   * @param o
   * @return
   */
  public String getText(Object o) {
    if(o == null)
      return null;
    String result = labelDispatcher.invoke(o);
    return result == null && o instanceof EObject
        ? labelDispatcher.invoke(((EObject) o).eContainingFeature(), o)
        : result;

  }

  public IEObjectDescription xref(Object o) {
    if(o == null)
      return null;
    return xrefDispatcher.invoke(o);
  }

}
TOP

Related Classes of com.puppetlabs.geppetto.pp.dsl.ui.editor.hover.PPDocumentationProvider

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.