Package de.sebastianbenz.task.impl

Source Code of de.sebastianbenz.task.impl.ContentImplCustom

/*******************************************************************************
* Copyright (c) 2011 Sebastian Benz.
* 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:
*     Sebastian Benz - initial API and implementation
******************************************************************************/
package de.sebastianbenz.task.impl;

import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Maps.newTreeMap;
import static java.util.regex.Pattern.compile;

import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;

import de.sebastianbenz.task.Container;
import de.sebastianbenz.task.Content;
import de.sebastianbenz.task.EmptyLine;
import de.sebastianbenz.task.Image;
import de.sebastianbenz.task.Link;
import de.sebastianbenz.task.Tag;
import de.sebastianbenz.task.TaskFactory;
import de.sebastianbenz.task.TaskModel;
import de.sebastianbenz.task.TaskPackage;
import de.sebastianbenz.task.Text;
import de.sebastianbenz.task.TextSegment;
import de.sebastianbenz.task.tagging.Tags;
import de.sebastianbenz.task.util.Images;
import de.sebastianbenz.task.util.Links;

public class ContentImplCustom extends de.sebastianbenz.task.impl.ContentImpl {

  private static final Pattern INTEND = Pattern.compile(" {2}|\t");
 
  public static final String DONE_TAG = "done";

  private int level = -1;

  @Override
  public int getLevel() {
    if(level == -1){
      level = 0;
      Matcher matcher = INTEND.matcher(getIntend());
      while(matcher.find()){
        level++;
      }
    }
    return level ;
  }
 
  @Override
  public String getIntend() {
    String result = super.getIntend();
    if(result == null){
      result = "";
    }
    return result;
  }
  private static final int SPACE = 1;

  private enum DoneStatus {
    UNKNOWN, OPEN, COMPLETED
  }
 
  public static final String TAG = "(^|\\W)@([\\w������]+)(\\((.*?)\\))?";
  private static final String URL = "[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]";
  private static final Pattern TAG_PATTERN = Pattern.compile(TAG, Pattern.DOTALL);
  private static final Pattern URL_DESCRIPTION_PATTERN = compile("(!)?\\[([-A-Za-z0-9+&@#/%?=~_()|!:,.;\\s]+)\\]\\((" + URL + ")\\)|\\(?\\b(http://|www[.])" + URL);
 
  private DoneStatus isDone = DoneStatus.UNKNOWN;
  private String value;

  @Override
  public EList<Tag> getTags() {
    if (tags == null) {
      tags = new EObjectContainmentEList<Tag>(Tag.class, this,
          TaskPackage.TASK__TAGS);
      parseTags();
    }
    return tags;
  }

  @Override
  public Container getParent() {
    if (parent == null) {
      setParent(resolveContainer());
    }
    return parent;
  }

  protected Container resolveContainer() {
    TaskModel taskModel = getTaskModel();
    if(taskModel == null){
      return null;
    }
    EList<Content> allContents = taskModel.getContents();
    int index = allContents.indexOf(this);
    if(index == 0){
      return taskModel;
    }
    for (int i = index - 1; i >= 0; i--) {
      Content candidate = allContents.get(i);
      if (!(candidate instanceof EmptyLine) && candidate.getLevel() < getLevel()) {
        return (Container) candidate;
      }
    }
    return taskModel;
  }

  @Override
  public boolean isDone() {
    if (isDone == DoneStatus.UNKNOWN) {
      isDone = resolveStatus();
    }
    return isDone == DoneStatus.COMPLETED;
  }

  protected DoneStatus resolveStatus() {
    for (Tag tag : getTags()) {
      if (tag.getName().equals(DONE_TAG)) {
        return DoneStatus.COMPLETED;
      }
    }
    if (getParent() instanceof Content) {
      Content parent = (Content) getParent();
      if (parent.isDone()) {
        return DoneStatus.COMPLETED;
      }
    }
    return DoneStatus.OPEN;
  }

  @Override
  public String getValue() {
    if(value == null){
      if(getText() == null){
        value = "";
      }else{
        value = removeTags(getText());
        value = cleanText(value);
      }
    }
    return value;
  }

  @Override
  public void setText(String newText) {
    tags = null;
    isDone = DoneStatus.UNKNOWN;
    value = null;
    super.setText(newText);
  }

  protected String removeTags(String string) {
    return string.replaceAll(TAG, "").trim().replaceAll("  ", " ");
  }

  protected String cleanText(String text){
    return text;
  }
 
  @Override
  public EList<Link> getLinks() {
    if(links == null){
      parseLinksAndImages();
     
    }
    return links;
  }

  protected void parseTags() {
    if(text == null){
      return;
    }
    Matcher matcher = TAG_PATTERN.matcher(text);
    while (matcher.find()) {
      String name = matcher.group(2);
      String value = matcher.group(4);
      int offset = matcher.start() + SPACE;
      int length = matcher.end() - offset;
      getTags().add(Tags.create(name, value, offset, length));
    }
  }
 
  @Override
  public EList<Image> getImages() {
    if(images == null){
      parseLinksAndImages();
    }
    return images;
  }

  private void parseLinksAndImages() {
    links = new EObjectContainmentEList<Link>(Link.class, this,
        TaskPackage.CONTENT__LINKS);
    images = new EObjectContainmentEList<Image>(Image.class, this,
        TaskPackage.CONTENT__IMAGES);
   
    if (text == null) {
      return;
    }
    Matcher matcher = URL_DESCRIPTION_PATTERN.matcher(text);
    while (matcher.find()) {
      int offset = matcher.start();
      int length = matcher.end() - offset;

      String description = "";
      String url;
      if(isImage(matcher)){
        description = matcher.group(2);
        url = matcher.group(3);
        images.add(Images.create(description, url, offset, length));
      }else if(isLinkWithDescription(matcher)){
        description = matcher.group(2);
        url = matcher.group(3);
        links.add(Links.create(description, url, offset, length));
      }else{
        url = matcher.group();
        links.add(Links.create(description, url, offset, length));
      }
    }
  }

  private boolean isImage(Matcher matcher) {
    return matcher.group(1) != null;
  }

  private boolean isLinkWithDescription(Matcher matcher) {
    return matcher.group(2) != null && matcher.group(3) != null;
  }
 
  @Override
  public EList<TextSegment> getSegments() {
    if(segments == null){
      segments = new EObjectResolvingEList<TextSegment>(TextSegment.class, this,
          TaskPackage.CONTENT__SEGMENTS);
      calculateSegments(segments);
    }
    return super.getSegments();
  }

  private void calculateSegments(EList<TextSegment> segments) {
    TreeMap<Integer, TextSegment> offsets = newTreeMap();
    add(offsets, concat(getLinks(), getTags(), getImages()));

    if(offsets.isEmpty()){
      addTextSegment(segments, 0, getText().length());
      return;
    }
   
    int begin = 0;
    for (TextSegment segment : offsets.values()) {
      int newOffset = segment.getOffset();
      if(newOffset > begin){
        addTextSegment(segments, begin, newOffset);
      }
      segments.add(segment);
      begin = newOffset + segment.getLength();
    }
    addTextSegment(segments, begin, getText().length());
  }

  protected void addTextSegment(EList<TextSegment> segments, int begin,
      int end) {
    if(begin >= end){
      return;
    }
    if(begin == end){
      return;
    }
    Text text = TaskFactory.eINSTANCE.createText();
    int textLength = end - begin;
    text.setOffset(begin);
    text.setLength(textLength);
    text.setValue(getText().substring(begin, begin + textLength));
    segments.add(text);
  }

  private void add(TreeMap<Integer, TextSegment> offsets, Iterable<? extends TextSegment> segments) {
    for (TextSegment s : segments) {
      offsets.put(s.getOffset(), s);
    }
  }

}
TOP

Related Classes of de.sebastianbenz.task.impl.ContentImplCustom

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.