Package org.locationtech.udig.jconsole

Source Code of org.locationtech.udig.jconsole.JavaEditor

/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* 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:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.locationtech.udig.jconsole;

import java.io.File;
import java.io.PrintStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;

import org.locationtech.udig.catalog.ID;
import org.locationtech.udig.catalog.IGeoResource;
import org.locationtech.udig.catalog.IService;
import org.locationtech.udig.internal.ui.UDigByteAndLocalTransfer;
import org.locationtech.udig.project.internal.impl.LayerImpl;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.URLTransfer;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.dnd.IDragAndDropService;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.joda.time.DateTime;

import org.locationtech.udig.jconsole.util.ImageCache;
import org.locationtech.udig.jconsole.util.Keywords;
import org.locationtech.udig.omsbox.OmsBoxPlugin;
import org.locationtech.udig.omsbox.core.IProcessListener;
import org.locationtech.udig.omsbox.core.JConsoleOutputConsole;
import org.locationtech.udig.omsbox.core.OmsScriptExecutor;
import org.locationtech.udig.omsbox.ui.RunningProcessListDialog;
import org.locationtech.udig.omsbox.utils.OmsBoxConstants;

/**
* Java specific text editor.
*/
public class JavaEditor extends TextEditor {
    public static final String ID = "org.locationtech.udig.jconsole.editor"; //$NON-NLS-1$

    /** The outline page */
    private JavaContentOutlinePage fOutlinePage;
    /** The projection support */
    private ProjectionSupport fProjectionSupport;
    private JConsoleOutputConsole outputConsole;

    private TextTransfer textTransfer;
    private FileTransfer fileTransfer;
    private URLTransfer urlTransfer;
    private UDigByteAndLocalTransfer udigTransfer;

    private static final String CONTENTASSIST_PROPOSAL_ID = "org.locationtech.udig.jconsole.java.JavaCompletionProcessor";

    /**
     * Default constructor.
     */
    public JavaEditor() {
        super();
        setDocumentProvider(new JavaEditorDocumentProvider());
        outputConsole = new JConsoleOutputConsole(null);
    }

    private Process process;

    private String filePath;

    public Process getProcess() {
        return process;
    }
    public void setProcess( Process process ) {
        this.process = process;
    }

    public JConsoleOutputConsole getOutputConsole() {
        return outputConsole;
    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method extend the
     * actions to add those specific to the receiver
     */
    protected void createActions() {
        super.createActions();

        ResourceBundle bundle = JavaEditorMessages.getResourceBundle();
        // This action will fire a CONTENTASSIST_PROPOSALS operation
        // when executed
        IAction action = new TextOperationAction(//
                bundle, "ContentAssistProposal", this, SourceViewer.CONTENTASSIST_PROPOSALS);
        action.setActionDefinitionId(CONTENTASSIST_PROPOSAL_ID);
        // Tell the editor about this new action
        setAction(CONTENTASSIST_PROPOSAL_ID, action);
        // Tell the editor to execute this action
        // when Ctrl+Spacebar is pressed
        setActionActivationCode(CONTENTASSIST_PROPOSAL_ID, ' ', -1, SWT.CTRL);
    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method performs any extra
     * disposal actions required by the java editor.
     */
    public void dispose() {
        ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[]{outputConsole});
        if (fOutlinePage != null)
            fOutlinePage.setInput(null);

        super.dispose();
    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method performs any extra
     * revert behavior required by the java editor.
     */
    public void doRevertToSaved() {
        super.doRevertToSaved();
        if (fOutlinePage != null)
            fOutlinePage.update();
    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method performs any extra
     * save behavior required by the java editor.
     *
     * @param monitor the progress monitor
     */
    public void doSave( IProgressMonitor monitor ) {
        super.doSave(monitor);
        if (fOutlinePage != null)
            fOutlinePage.update();
    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method performs any extra
     * save as behavior required by the java editor.
     */
    public void doSaveAs() {
        super.doSaveAs();
        if (fOutlinePage != null)
            fOutlinePage.update();
        // File lastOpenFolder = JConsolePlugin.getDefault().getLastOpenFolder();
        // FileDialog fileDialog = new FileDialog(this.getSite().getShell(), SWT.SAVE);
        // fileDialog.setFilterExtensions(new String[]{"*.jgrass"});
        // fileDialog.setFilterPath(lastOpenFolder.getAbsolutePath());
        // String path = fileDialog.open();
        // if (path == null || path.length() < 1) {
        // return;
        // }
        // File f = new File(path);
        // if (!f.getParentFile().exists()) {
        // return;
        // }

    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method performs sets the
     * input of the outline page after AbstractTextEditor has set input.
     *
     * @param input the editor input
     * @throws CoreException in case the input can not be set
     */
    public void doSetInput( IEditorInput input ) throws CoreException {
        super.doSetInput(input);
        if (input instanceof JavaFileEditorInput) {
            JavaFileEditorInput javaFile = (JavaFileEditorInput) input;
            filePath = javaFile.getAbsolutePath();
        }

        if (fOutlinePage != null)
            fOutlinePage.setInput(input);
    }

    /*
     * @see org.eclipse.ui.texteditor.ExtendedTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
     */
    protected void editorContextMenuAboutToShow( IMenuManager menu ) {
        super.editorContextMenuAboutToShow(menu);
        addAction(menu, "ContentAssistProposal"); //$NON-NLS-1$
        addAction(menu, "ContentAssistTip"); //$NON-NLS-1$
        //        addAction(menu, "DefineFoldingRegion"); //$NON-NLS-1$
    }

    /** The <code>JavaEditor</code> implementation of this
     * <code>AbstractTextEditor</code> method performs gets
     * the java content outline page if request is for a an
     * outline page.
     *
     * @param required the required type
     * @return an adapter for the required type or <code>null</code>
     */
    public Object getAdapter( Class required ) {
        if (IContentOutlinePage.class.equals(required)) {
            if (fOutlinePage == null) {
                fOutlinePage = new JavaContentOutlinePage(getDocumentProvider(), this);
                if (getEditorInput() != null)
                    fOutlinePage.setInput(getEditorInput());
            }
            return fOutlinePage;
        }

        if (fProjectionSupport != null) {
            Object adapter = fProjectionSupport.getAdapter(getSourceViewer(), required);
            if (adapter != null)
                return adapter;
        }

        return super.getAdapter(required);
    }

    /* (non-Javadoc)
     * Method declared on AbstractTextEditor
     */
    protected void initializeEditor() {
        super.initializeEditor();
        setSourceViewerConfiguration(new JavaSourceViewerConfiguration());
    }

    /*
     * @see org.eclipse.ui.texteditor.ExtendedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
     */
    protected ISourceViewer createSourceViewer( Composite parent, IVerticalRuler ruler, int styles ) {

        fAnnotationAccess = createAnnotationAccess();
        fOverviewRuler = createOverviewRuler(getSharedColors());

        ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
        // ensure decoration support has been created and configured.
        getSourceViewerDecorationSupport(viewer);

        return viewer;
    }

    /*
     * @see org.eclipse.ui.texteditor.ExtendedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    public void createPartControl( Composite parent ) {
        Composite mainComposite = new Composite(parent, SWT.NONE);
        mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        GridLayout mainLayout = new GridLayout(1, false);
        mainLayout.marginHeight = 0;
        mainLayout.marginWidth = 0;
        mainComposite.setLayout(mainLayout);

        addEditorActions(mainComposite);

        Composite editorComposite = new Composite(mainComposite, SWT.BORDER);
        editorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        FillLayout editorLayout = new FillLayout();
        editorLayout.marginHeight = 0;
        editorLayout.marginWidth = 0;
        editorComposite.setLayout(editorLayout);

        super.createPartControl(editorComposite);

        ProjectionViewer viewer = (ProjectionViewer) getSourceViewer();
        fProjectionSupport = new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
        fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
        fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
        fProjectionSupport.install();
        viewer.doOperation(ProjectionViewer.TOGGLE);

        // MultiPassContentFormatter formatter=
        // new MultiPassContentFormatter(
        // getConfiguredDocumentPartitioning(viewer),
        // IDocument.DEFAULT_CONTENT_TYPE);
        //
        // formatter.setMasterStrategy(
        // new JavaFormattingStrategy());
        // formatter.setSlaveStrategy(
        // new CommentFormattingStrategy(...),
        // IJavaPartitions.JAVA_DOC);
        //

        final IDragAndDropService dndService = (IDragAndDropService) this.getSite().getService(IDragAndDropService.class);
        StyledText st = viewer.getTextWidget();
        textTransfer = TextTransfer.getInstance();
        fileTransfer = FileTransfer.getInstance();
        urlTransfer = URLTransfer.getInstance();
        udigTransfer = UDigByteAndLocalTransfer.getInstance();
        Transfer[] types = new Transfer[]{fileTransfer, textTransfer, urlTransfer, udigTransfer};

        dndService.addMergedDropTarget(st, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT, //
                types, dropTargetListener);
    }

    private void addEditorActions( Composite mainComposite ) {
        Composite buttonsComposite = new Composite(mainComposite, SWT.NONE);
        buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        GridLayout buttonsLayout = new GridLayout(6, false);
        buttonsLayout.marginTop = 1;
        buttonsLayout.marginBottom = 0;
        buttonsLayout.marginWidth = 1;
        buttonsComposite.setLayout(buttonsLayout);

        Button startButton = new Button(buttonsComposite, SWT.PUSH);
        startButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        startButton.setToolTipText("Start the current script");
        startButton.setImage(ImageCache.getInstance().getImage(ImageCache.START));
        startButton.addSelectionListener(new SelectionAdapter(){
            public void widgetSelected( SelectionEvent e ) {
                startScript();
            }
        });
        Button stopButton = new Button(buttonsComposite, SWT.PUSH);
        stopButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        stopButton.setToolTipText("Stop a running script");
        stopButton.setImage(ImageCache.getInstance().getImage(ImageCache.STOP));
        stopButton.addSelectionListener(new SelectionAdapter(){
            public void widgetSelected( SelectionEvent e ) {
                stopScript();
            }
        });
        Button templateButton = new Button(buttonsComposite, SWT.PUSH);
        templateButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        templateButton.setToolTipText("Insert commonly used imports");
        templateButton.setImage(ImageCache.getInstance().getImage(ImageCache.TEMPLATE));
        templateButton.addSelectionListener(new SelectionAdapter(){
            public void widgetSelected( SelectionEvent e ) {
                insertTemplates();
            }
        });

        Label spacer = new Label(buttonsComposite, SWT.NONE);
        spacer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Combo heapCombo = new Combo(buttonsComposite, SWT.DROP_DOWN);
        heapCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        heapCombo.setItems(OmsBoxConstants.HEAPLEVELS);
        heapCombo.setToolTipText("Memory [MB]");
        int savedHeapLevel = OmsBoxPlugin.getDefault().retrieveSavedHeap();
        for( int i = 0; i < OmsBoxConstants.HEAPLEVELS.length; i++ ) {
            if (OmsBoxConstants.HEAPLEVELS[i].equals(String.valueOf(savedHeapLevel))) {
                heapCombo.select(i);
                break;
            }
        }
        heapCombo.addSelectionListener(new SelectionAdapter(){
            public void widgetSelected( SelectionEvent e ) {
                String item = heapCombo.getText();
                OmsBoxPlugin.getDefault().saveHeap(Integer.parseInt(item));
            }
        });
        heapCombo.addModifyListener(new ModifyListener(){
            public void modifyText( ModifyEvent e ) {
                String item = heapCombo.getText();
                try {
                    Integer.parseInt(item);
                } catch (Exception ex) {
                    return;
                }
                if (item.length() > 0) {
                    OmsBoxPlugin.getDefault().saveHeap(Integer.parseInt(item));
                }
            }
        });

        final Combo logCombo = new Combo(buttonsComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
        logCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        logCombo.setItems(OmsBoxConstants.LOGLEVELS_GUI);
        logCombo.setToolTipText("Enable/disable logging");
        String savedLogLevel = OmsBoxPlugin.getDefault().retrieveSavedLogLevel();
        for( int i = 0; i < OmsBoxConstants.LOGLEVELS_GUI.length; i++ ) {
            if (OmsBoxConstants.LOGLEVELS_GUI[i].equals(savedLogLevel)) {
                logCombo.select(i);
                break;
            }
        }
        logCombo.addSelectionListener(new SelectionAdapter(){
            public void widgetSelected( SelectionEvent e ) {
                String item = logCombo.getText();
                OmsBoxPlugin.getDefault().saveLogLevel(item);
            }
        });

    }

    private DropTargetListener dropTargetListener = new DropTargetAdapter(){
        public void drop( DropTargetEvent event ) {
            if (textTransfer.isSupportedType(event.currentDataType)) {
                String text = (String) event.data;
                System.out.println(text);
            }
            if (fileTransfer.isSupportedType(event.currentDataType)) {
                String[] files = (String[]) event.data;
                if (files.length > 0) {
                    File file = new File(files[0]);
                    if (file.exists()) {
                        pasteDropContent(file);
                        JConsolePlugin.getDefault().setLastOpenFolder(file.getParentFile().getAbsolutePath());
                    }
                }
            }
            if (urlTransfer.isSupportedType(event.currentDataType)) {
                Object data2 = event.data;
                System.out.println(data2);
            }
            if (udigTransfer.isSupportedType(event.currentDataType)) {
                try {
                    Object data = event.data;
                    if (data instanceof TreeSelection) {
                        TreeSelection selection = (TreeSelection) data;
                        Object firstElement = selection.getFirstElement();

                        IGeoResource geoResource = null;
                        if (firstElement instanceof LayerImpl) {
                            LayerImpl layer = (LayerImpl) firstElement;
                            geoResource = layer.getGeoResource();

                        }
                        if (firstElement instanceof IService) {
                            IService service = (IService) firstElement;
                            List< ? extends IGeoResource> resources = service.resources(new NullProgressMonitor());
                            if (resources.size() > 0) {
                                geoResource = resources.get(0);
                            }
                        }
                        if (geoResource != null) {
                            ID id = geoResource.getID();
                            if (id != null)
                                if (id.isFile()) {
                                    File file = id.toFile();
                                    if (file.exists()) {
                                        pasteDropContent(file);
                                        JConsolePlugin.getDefault().setLastOpenFolder(file.getParentFile().getAbsolutePath());
                                    }
                                } else if (id.toString().contains("#") && id.toString().startsWith("file")) {
                                    // try to get the file
                                    String string = id.toString().replaceAll("#", "");
                                    URL url = new URL(string);
                                    File file = new File(url.toURI());
                                    if (file.exists()) {
                                        pasteDropContent(file);
                                        JConsolePlugin.getDefault().setLastOpenFolder(file.getParentFile().getAbsolutePath());
                                    }
                                } else {
                                    System.out.println("Not a file: " + id.toString());
                                }
                        }

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        };
    };

    private void pasteDropContent( File file ) {
        String path = file.getAbsolutePath();
        try {
            IDocumentProvider dp = getDocumentProvider();
            IDocument doc = dp.getDocument(getEditorInput());
            // int numberOfLines = doc.getNumberOfLines() - 1;
            // int offset = doc.getLineOffset(numberOfLines);

            ISelectionProvider selectionProvider = getSelectionProvider();
            ISelection selection = selectionProvider.getSelection();
            if (selection instanceof ITextSelection) {
                ITextSelection textSelection = (ITextSelection) selection;
                int offset = textSelection.getOffset();
                doc.replace(offset, 0, path);
            }
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    /*
     * @see org.eclipse.ui.texteditor.AbstractTextEditor#adjustHighlightRange(int, int)
     */
    protected void adjustHighlightRange( int offset, int length ) {
        ISourceViewer viewer = getSourceViewer();
        if (viewer instanceof ITextViewerExtension5) {
            ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
            extension.exposeModelRange(new Region(offset, length));
        }
    }

    private void insertTemplates() {
        IDocument doc = getDocumentProvider().getDocument(getEditorInput());
        String text = doc.get();
        StringBuilder sb = new StringBuilder();
        List<String> values = Keywords.getValues(Keywords.IMPORTS);
        for( String value : values ) {
            sb.append(value).append("\n");
        }

        StringBuilder finalSb = new StringBuilder();
        finalSb.append(sb.toString());
        finalSb.append("\n");
        finalSb.append(text);

        doc.set(finalSb.toString());

    }

    private void stopScript() {
        HashMap<String, Process> runningProcessesMap = OmsBoxPlugin.getDefault().getRunningProcessesMap();

        Shell shell = getEditorSite().getShell();
        if (runningProcessesMap.size() == 0) {
            MessageDialog.openInformation(shell, "Process List", "No running processes available at the current time");
        } else {
            RunningProcessListDialog dialog = new RunningProcessListDialog();
            dialog.open(shell, SWT.MULTI);
        }
    }

    private void startScript() {
        IDocument doc = getDocumentProvider().getDocument(getEditorInput());
        // JConsoleOutputConsole outputConsole = getOutputConsole();
        // outputConsole.clearConsole();

        String text = null;
        ISelection selection = getSelectionProvider().getSelection();
        if (selection instanceof ITextSelection) {
            ITextSelection textSelection = (ITextSelection) selection;
            if (!textSelection.isEmpty()) {
                text = textSelection.getText();

                if (text.trim().length() > 0 && !text.trim().startsWith("import")) {
                    // something in the middle was selected, we need to add the imports
                    StringBuilder sb = new StringBuilder();
                    List<String> defaultImports = Keywords.getValues(Keywords.IMPORTS);
                    for( String defaultImport : defaultImports ) {
                        sb.append(defaultImport).append("\n");
                    }
                    sb.append(text);
                    text = sb.toString();
                }
            }
        }
        if (text == null || 0 >= text.length()) {
            text = doc.get();
        }

        String dateTimeString = new DateTime().toString(OmsBoxConstants.dateTimeFormatterYYYYMMDDHHMMSS);

        String title = getTitle();
        JConsoleOutputConsole outputConsole = new JConsoleOutputConsole("Script: " + title + " (" + dateTimeString + " )");
        outputConsole.clearConsole();

        PrintStream internalStream = outputConsole.internal;
        // PrintStream outputStream = outputConsole.out;
        PrintStream errorStream = outputConsole.err;
        // open console
        IConsoleManager manager = org.eclipse.ui.console.ConsolePlugin.getDefault().getConsoleManager();
        manager.addConsoles(new IConsole[]{outputConsole});
        manager.showConsoleView(outputConsole);

        try {
            final String scriptID = "geoscript_" + dateTimeString;
            OmsScriptExecutor executor = new OmsScriptExecutor();
            String loggerLevelGui = OmsBoxPlugin.getDefault().retrieveSavedLogLevel();
            String ramLevel = String.valueOf(OmsBoxPlugin.getDefault().retrieveSavedHeap());
            executor.addProcessListener(new IProcessListener(){
                public void onProcessStopped() {
                    OmsBoxPlugin.getDefault().cleanProcess(scriptID);
                }
            });
            Process process = executor.exec(text, internalStream, errorStream, loggerLevelGui, ramLevel);
            OmsBoxPlugin.getDefault().addProcess(process, scriptID);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
TOP

Related Classes of org.locationtech.udig.jconsole.JavaEditor

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.