org.openlegacy.ide.eclipse.preview.screen.ScreenPreview.java Source code

Java tutorial

Introduction

Here is the source code for org.openlegacy.ide.eclipse.preview.screen.ScreenPreview.java

Source

/*******************************************************************************
 * Copyright (c) 2014 OpenLegacy Inc.
 * 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:
 *     OpenLegacy Inc. - initial API and implementation
 *******************************************************************************/
package org.openlegacy.ide.eclipse.preview.screen;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CaretEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.openlegacy.ide.eclipse.components.ImageComposite;
import org.openlegacy.ide.eclipse.components.screen.SnapshotComposite;
import org.openlegacy.ide.eclipse.preview.AbstractEntityPreview;
import org.openlegacy.ide.eclipse.util.PathsUtil;
import org.openlegacy.terminal.TerminalField;
import org.openlegacy.terminal.TerminalPosition;
import org.openlegacy.terminal.TerminalSnapshot;
import org.openlegacy.terminal.render.DefaultTerminalSnapshotImageRenderer;
import org.openlegacy.terminal.support.DefaultTerminalSnapshotsLoader;
import org.openlegacy.terminal.support.SimpleTerminalPosition;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class ScreenPreview extends AbstractEntityPreview {

    private static final String IDENTIFIER_ANNOTATION = "org.openlegacy.annotations.screen.Identifier";
    private static final String SCREEN_ENTITY_ANNOTATION = "org.openlegacy.annotations.screen.ScreenEntity";
    private static final String SCREEN_ENTITY_ANNOTATION_SHORT = "ScreenEntity";
    private static final String SCREEN_FIELD_ANNOTATION = "org.openlegacy.annotations.screen.ScreenField";
    /**
     * The ID of the view as specified by the extension.
     */
    public static final String ID = "org.openlegacy.ide.eclipse.preview.ScreenPreview";

    private SnapshotComposite snapshotComposite;

    private TerminalSnapshot terminalSnapshot;

    private final String XML_EXTENSION = ".xml";

    private static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
        List<T> r = new ArrayList<T>(c.size());
        for (Object o : c) {
            r.add(clazz.cast(o));
        }
        return r;
    }

    private static boolean isInteger(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private boolean checkVisitedAnnotation(NormalAnnotation annotation) {
        int row = 0;
        int col = 0;
        int endCol = 0;
        String val = "";

        List<MemberValuePair> values = castList(MemberValuePair.class, annotation.values());
        for (MemberValuePair pair : values) {
            SimpleName key = pair.getName();
            String value = pair.getValue().toString();
            if (key.getIdentifier().equalsIgnoreCase("row") && isInteger(value)) {
                row = new Integer(value).intValue();
            }
            if (key.getIdentifier().equalsIgnoreCase("column") && isInteger(value)) {
                col = new Integer(value).intValue();
            }
            if (key.getIdentifier().equalsIgnoreCase("endColumn") && isInteger(value)) {
                endCol = new Integer(value).intValue();
            }
            if (key.getIdentifier().equalsIgnoreCase("value")) {
                val = value;
            }
        }
        snapshotComposite.addDrawingRectangle(getRectangle(row, row, col, endCol, val), SWT.COLOR_YELLOW, true);
        return true;
    }

    private Rectangle getRectangle(int row, int endRow, int column, int endColumn, String value) {
        if (terminalSnapshot == null) {
            return new Rectangle(0, 0, 0, 0);
        }
        DefaultTerminalSnapshotImageRenderer renderer = new DefaultTerminalSnapshotImageRenderer();

        int length = 0;
        if (endColumn == 0) {
            SimpleTerminalPosition terminalPosition = new SimpleTerminalPosition(row, column);
            TerminalField field = terminalSnapshot.getField(terminalPosition);
            if (field != null) {
                TerminalPosition endPosition = field.getEndPosition();
                endColumn = endPosition.getColumn();
            } else {
                // if column attribute was changed then calculate endColumn
                endColumn = column + value.length() - 1;
            }
        }
        length = endColumn - column + 1;

        int x = renderer.toWidth(column - 1 + renderer.getLeftColumnsOffset());
        int y = renderer.toHeight(row - 1) + renderer.getTopPixelsOffset();
        int width = renderer.toWidth(length);
        int height = renderer.toHeight(1);
        if (endRow >= row) {
            height = renderer.toHeight(endRow - row + 1);
        }
        return new Rectangle(x, y, width, height);
    }

    @Override
    protected IFile getSourceFile(IPath path) {
        String className = path.lastSegment().replace("." + path.getFileExtension(), "");
        StringBuilder builder = new StringBuilder(path.removeFileExtension().toOSString());
        builder.append("-resources");
        builder.append(File.separator);
        builder.append(className + XML_EXTENSION);

        return getFile(builder.toString());

    }

    private void handleCaretMoved(int widgetCaretOffset) {
        IJavaElement javaInput = getJavaInput();
        if (javaInput == null) {
            return;
        }

        String key = javaInput.getPath().toOSString();
        CompilationUnit cu = getCacheCompilationUnitContainer().get(key);
        if (cu == null) {
            return;
        }
        IEditorPart activeEditor = getActiveEditor();

        final AtomicInteger offset = new AtomicInteger(0);
        ITextOperationTarget target = (ITextOperationTarget) activeEditor.getAdapter(ITextOperationTarget.class);
        if (target instanceof ITextViewer) {
            TextViewer textViewer = (TextViewer) target;
            offset.set(textViewer.widgetOffset2ModelOffset(widgetCaretOffset));
        }

        final AtomicBoolean isAnnotationVisited = new AtomicBoolean(false);

        cu.accept(new ASTVisitor() {

            @Override
            public void endVisit(FieldDeclaration node) {
                super.endVisit(node);
                if (isAnnotationVisited.get()) {
                    return;
                }
                if ((offset.get() < node.getStartPosition())
                        || (offset.get() > (node.getStartPosition() + node.getLength()))) {
                    return;
                }
                List<ASTNode> modifiers = castList(ASTNode.class, node.modifiers());
                for (ASTNode astNode : modifiers) {
                    if (astNode instanceof NormalAnnotation) {
                        ITypeBinding binding = ((NormalAnnotation) astNode).resolveTypeBinding();
                        // binding can be null, for example if user copy field with annotation
                        if (binding == null) {
                            continue;
                        }
                        if (binding.getQualifiedName().equals(SCREEN_FIELD_ANNOTATION)) {
                            // retrieve rectangle from annotation attributes
                            isAnnotationVisited.set(checkVisitedAnnotation((NormalAnnotation) astNode));
                        }
                    }
                }
            }

            @Override
            public void endVisit(NormalAnnotation node) {
                super.endVisit(node);
                if (isAnnotationVisited.get()) {
                    return;
                }
                if ((offset.get() < node.getStartPosition())
                        || (offset.get() > (node.getStartPosition() + node.getLength()))) {
                    snapshotComposite.addDrawingRectangle(null);
                    return;
                }
                ITypeBinding binding = node.resolveTypeBinding();
                // binding can be null, for example if user copy field with annotation
                if (binding == null) {
                    return;
                }
                if (binding.getQualifiedName().equals(IDENTIFIER_ANNOTATION)
                        || binding.getQualifiedName().equals(SCREEN_FIELD_ANNOTATION)) {
                    // retrieve rectangle from annotation attributes
                    isAnnotationVisited.set(checkVisitedAnnotation(node));
                }
            }

        });
    }

    @Override
    protected void showPreviewImage(IJavaElement javaInput, IFile xmlFile) {

        if (xmlFile != null && xmlFile.exists()) {
            // show snapshot composite
            DefaultTerminalSnapshotsLoader loader = new DefaultTerminalSnapshotsLoader();
            terminalSnapshot = loader.load(new File(xmlFile.getLocationURI()).getAbsolutePath());
            snapshotComposite.setSnapshot(terminalSnapshot);
            snapshotComposite.setVisible(true);
            snapshotComposite.setProjectPath(PathsUtil.toOsLocation(xmlFile.getProject()));
            return;
        }
        // hide image
        snapshotComposite.setVisible(false);
    }

    public void addFieldRectangle(FieldRectangle rectangle) {
        addFieldRectangle(rectangle, SWT.COLOR_YELLOW, false);
    }

    public void addFieldRectangle(FieldRectangle rectangle, int color) {
        addFieldRectangle(rectangle, color, false);
    }

    public void addFieldRectangle(FieldRectangle rectangle, int color, boolean clearListBeforeAdd) {
        if (rectangle != null) {
            this.snapshotComposite.addDrawingRectangle(getRectangle(rectangle.getRow(), rectangle.getEndRow(),
                    rectangle.getColumn(), rectangle.getEndColumn(), rectangle.getValue()), color,
                    clearListBeforeAdd);
        }
    }

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    @Override
    public void createPartControl(Composite parent) {
        File projectPath = null;
        IEditorPart editor = getActiveEditor();
        if (editor != null) {
            FileEditorInput input = (FileEditorInput) getActiveEditor().getEditorInput();
            projectPath = PathsUtil.toOsLocation(input.getFile().getProject());
        }
        snapshotComposite = new SnapshotComposite(parent, projectPath);
        snapshotComposite.setIsScalable(true);
    }

    public SelectedObject getSelectedObject() {
        return this.snapshotComposite.getSelectedObject();
    }

    @Override
    public void handleCaretMoved(CaretEvent caretEvent) {
        handleCaretMoved(caretEvent.caretOffset);
    }

    @Override
    public void handleModifyText(ModifyEvent event) {
        IJavaElement javaInput = getJavaInput();
        if (javaInput == null) {
            return;
        }
        String key = javaInput.getPath().toOSString();
        if (!getCacheCompilationUnitContainer().containsKey(key)) {
            return;
        }
        CompilationUnit cu = createParser((ICompilationUnit) javaInput);
        getCacheCompilationUnitContainer().put(key, cu);
        StyledText styledText = getCacheStyledTextContainer().get(key);
        if ((styledText != null) && !styledText.isDisposed()) {
            this.handleCaretMoved(styledText.getCaretOffset());
        }
    }

    @Override
    protected String getEntityAnnotationShort() {
        return SCREEN_ENTITY_ANNOTATION_SHORT;
    }

    @Override
    protected String getEntityAnnotation() {
        return SCREEN_ENTITY_ANNOTATION;
    }

    @Override
    protected ImageComposite getImageComposite() {
        return snapshotComposite;
    }

    public IEditorPart getLastActiveEditor() {
        return lastActiveEditor;
    }

    public SelectedObject getSelectedObject(int row, int column) {
        return snapshotComposite.getSelectedObject(row, column);
    }

    public static boolean canCreateFieldFromSelection() {
        ScreenPreview screenPreview = (ScreenPreview) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                .getActivePage().findView(ScreenPreview.ID);
        if (screenPreview != null) {
            SelectedObject selectedObject = screenPreview.getSelectedObject();
            if (selectedObject != null) {
                return !selectedObject.isStartsWithSeparator();
            }
        }
        return true;
    }

}