org.eclipse.birt.data.oda.pojo.ui.util.Utils.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.birt.data.oda.pojo.ui.util.Utils.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/
package org.eclipse.birt.data.oda.pojo.ui.util;

import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.datatools.connectivity.internal.ui.dialogs.ExceptionHandler;
import org.eclipse.datatools.connectivity.oda.OdaException;
import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
import org.eclipse.datatools.connectivity.oda.design.DataSourceDesign;
import org.eclipse.datatools.connectivity.oda.design.ResourceIdentifiers;
import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.birt.data.oda.pojo.querymodel.ClassColumnMappings;
import org.eclipse.birt.data.oda.pojo.querymodel.Column;
import org.eclipse.birt.data.oda.pojo.querymodel.ColumnReferenceNode;
import org.eclipse.birt.data.oda.pojo.querymodel.ConstantParameter;
import org.eclipse.birt.data.oda.pojo.querymodel.FieldSource;
import org.eclipse.birt.data.oda.pojo.querymodel.IColumnsMapping;
import org.eclipse.birt.data.oda.pojo.querymodel.IMappingSource;
import org.eclipse.birt.data.oda.pojo.querymodel.IMethodParameter;
import org.eclipse.birt.data.oda.pojo.querymodel.MethodSource;
import org.eclipse.birt.data.oda.pojo.querymodel.OneColumnMapping;
import org.eclipse.birt.data.oda.pojo.querymodel.PojoQuery;
import org.eclipse.birt.data.oda.pojo.querymodel.ReferenceGraph;
import org.eclipse.birt.data.oda.pojo.querymodel.RelayReferenceNode;
import org.eclipse.birt.data.oda.pojo.querymodel.VariableParameter;
import org.eclipse.birt.data.oda.pojo.ui.Activator;
import org.eclipse.birt.data.oda.pojo.ui.i18n.Messages;
import org.eclipse.birt.data.oda.pojo.ui.impl.models.ColumnDefinition;
import org.eclipse.birt.data.oda.pojo.ui.impl.models.OdaType;
import org.eclipse.birt.data.oda.pojo.util.PojoQueryWriter;
import org.eclipse.birt.data.oda.pojo.util.URLParser;

/**
 * 
 */

public class Utils {

    private static Logger logger = Logger.getLogger(Utils.class.getName());

    private static final String METHOD_FLAG = ".+\\(.*\\)$"; //$NON-NLS-1$
    private static final String BEAN_NAME_REGEX = "^(get|is)[A-Z].*"; //$NON-NLS-1$

    private static final String CLASS_IMG_FLAG = "classImgFlag"; //$NON-NLS-1$
    private static final String FIELD_IMG_FLAG = "fieldImgFlag"; //$NON-NLS-1$
    private static final String METHOD_IMG_FLAG = "methodImgFlag"; //$NON-NLS-1$
    private static final String WARNING_IMG_FLAG = "warningImgFlag"; //$NON-NLS-1$

    //The icons DESIGNTIME_IMG_FLAG and RUNTIME_IMG_FLAG are discarded to use for the TabItem
    //But still preserve the 2 icon files and the entries
    private static final String DESIGNTIME_IMG_FLAG = "DesignTimeImgFlag"; //$NON-NLS-1$
    private static final String RUNTIME_IMG_FLAG = "RunTimeImgFlag"; //$NON-NLS-1$

    private static final String FOLDER_ICON = "FolderIcon"; //$NON-NLS-1$
    private static final String JAR_ICON = "JarIcon"; //$NON-NLS-1$
    private static final String OK_DISABLE_ICON = "OKDisableIcon"; //$NON-NLS-1$
    private static final String FAIL_DISABLE_ICON = "FailDisableIcon"; //$NON-NLS-1$

    static {
        ImageRegistry reg = JFaceResources.getImageRegistry();
        reg.put(CLASS_IMG_FLAG, ImageDescriptor.createFromFile(Activator.class, "/icons/class_obj.gif"));//$NON-NLS-1$
        reg.put(FIELD_IMG_FLAG, ImageDescriptor.createFromFile(Activator.class, "/icons/field_public_obj.gif"));//$NON-NLS-1$
        reg.put(METHOD_IMG_FLAG, ImageDescriptor.createFromFile(Activator.class, "/icons/method_public_obj.gif"));//$NON-NLS-1$
        reg.put(WARNING_IMG_FLAG, ImageDescriptor.createFromFile(Activator.class, "/icons/warning_obj.gif"));//$NON-NLS-1$
        reg.put(DESIGNTIME_IMG_FLAG, ImageDescriptor.createFromFile(Activator.class, "/icons/icon_designtime.gif"));//$NON-NLS-1$
        reg.put(RUNTIME_IMG_FLAG, ImageDescriptor.createFromFile(Activator.class, "/icons/icon_runtime.gif"));//$NON-NLS-1$
        reg.put(FOLDER_ICON, ImageDescriptor.createFromFile(Activator.class, "/icons/folder_icon.gif"));//$NON-NLS-1$
        reg.put(JAR_ICON, ImageDescriptor.createFromFile(Activator.class, "/icons/jar_icon.gif"));//$NON-NLS-1$
        reg.put(OK_DISABLE_ICON, ImageDescriptor.createFromFile(Activator.class, "/icons/ok_tbl_disabled.gif"));//$NON-NLS-1$
        reg.put(FAIL_DISABLE_ICON, ImageDescriptor.createFromFile(Activator.class, "/icons/fail_tbl_disabled.gif"));//$NON-NLS-1$
    }

    private Utils() {
    };

    public static URLParser createURLParser(ResourceIdentifiers ri) {
        if (ri == null) {
            return new URLParser(null);
        }
        return new URLParser(DesignSessionUtil.createResourceIdentifiersContext(ri));
    }

    public static OdaType getSuggestOdaType(Member m) {
        if (m instanceof Method) {
            return getSuggerstOdaType(((Method) m).getReturnType());
        } else if (m instanceof Field) {
            return getSuggerstOdaType(((Field) m).getType());
        }
        assert false;
        return OdaType.String;
    }

    @SuppressWarnings("unchecked")
    private static OdaType getSuggerstOdaType(Class type) {
        //Primitive or its wrapper 
        if (type == Boolean.TYPE || type == Boolean.class) {
            return OdaType.Boolean;
        }
        if (type == Character.TYPE || type == Character.class) {
            return OdaType.String;
        }
        if (type == Byte.TYPE || type == Byte.class) {
            return OdaType.Integer;
        }
        if (type == Short.TYPE || type == Short.class) {
            return OdaType.Integer;
        }
        if (type == Integer.TYPE || type == Integer.class) {
            return OdaType.Integer;
        }
        if (type == Long.TYPE || type == Long.class) {
            return OdaType.Double;
        }
        if (type == Float.TYPE || type == Float.class) {
            return OdaType.Double;
        }
        if (type == Double.TYPE || type == Double.class) {
            return OdaType.Double;
        }

        if (BigDecimal.class.isAssignableFrom(type)) {
            return OdaType.Decimal;
        }
        if (java.sql.Blob.class.isAssignableFrom(type)) {
            return OdaType.Blob;
        }
        if (java.sql.Clob.class.isAssignableFrom(type)) {
            return OdaType.String;
        }
        if (java.sql.Time.class.isAssignableFrom(type)) {
            return OdaType.Time;
        }
        if (java.sql.Timestamp.class.isAssignableFrom(type)) {
            return OdaType.Timestamp;
        }
        if (java.util.Date.class.isAssignableFrom(type)) {
            return OdaType.Date;
        }
        if (type == String.class) {
            return OdaType.String;
        }
        //For other types
        return OdaType.Object;
    }

    public static String getSuggestName(Member m) {
        String name = m.getName();
        if (m instanceof Method) {
            if (name.matches(BEAN_NAME_REGEX)) {
                if (name.startsWith("get")) //$NON-NLS-1$
                {
                    return name.substring(3);
                }
                //starts with "is"
                return name.substring(2);
            } else {
                return upperFirstChar(name);
            }
        } else if (m instanceof Field) {
            return upperFirstChar(name);

        }
        assert false;
        return m.getName();
    }

    private static String upperFirstChar(String name) {
        assert name != null && name.length() > 0;
        if (Character.isLowerCase(name.charAt(0))) {
            //Upper case the first char if necessary
            return name.replaceFirst(String.valueOf(name.charAt(0)),
                    String.valueOf(Character.toUpperCase(name.charAt(0))));
        }
        return name;
    }

    public static void updateColumnMappings(PojoQuery pq, ColumnDefinition[] cds) {
        assert pq != null && cds != null;
        pq.clearColumnMappings();
        for (int i = 0; i < cds.length; i++) {
            IMappingSource[] mss = cds[i].getMappingPath();
            ClassColumnMappings parent = null;
            for (int j = 0; j <= mss.length - 2; j++) {
                ClassColumnMappings ccm = new ClassColumnMappings(mss[j]);
                if (parent == null) {
                    parent = addClassColumnMappings(pq, ccm);
                } else {
                    parent = addClassColumnMappings(parent, ccm);
                }
            }
            Column c = new Column(cds[i].getName(), cds[i].getType().getName(), i + 1);
            assert mss.length >= 1;
            IColumnsMapping cm = new OneColumnMapping(mss[mss.length - 1], c);
            if (parent == null) {
                pq.addColumnsMapping(cm);
            } else {
                parent.addColumnsMapping(cm);
            }
        }
    }

    public static ColumnDefinition[] getColumnDefinitions(PojoQuery pq) throws OdaException {
        assert pq != null;
        ReferenceGraph rg = ReferenceGraph.create(pq);
        ColumnDefinition[] cds = new ColumnDefinition[rg.getColumnReferences().length];
        int index = 0;
        for (ColumnReferenceNode crn : rg.getColumnReferences()) {
            String name = crn.getColumn().getName();
            OdaType type = OdaType.getInstance(crn.getColumn().getOdaType());
            if (type == null) {
                logger.log(Level.WARNING, "Unkown Oda type: " + crn.getColumn().getOdaType()); //$NON-NLS-1$
                type = OdaType.String;
            }
            Stack<IMappingSource> mss = new Stack<IMappingSource>();
            mss.push(crn.getReference());
            RelayReferenceNode rrn = crn.getParent();
            while (rrn != null) {
                mss.push(rrn.getReference());
                rrn = rrn.getParent();
            }
            IMappingSource[] mappingPath = new IMappingSource[mss.size()];
            for (int i = 0; i < mappingPath.length; i++) {
                mappingPath[i] = mss.pop();
            }
            cds[index] = new ColumnDefinition(mappingPath, name, type);
            index++;
        }
        return cds;
    }

    private static ClassColumnMappings addClassColumnMappings(PojoQuery pq, ClassColumnMappings ccm) {
        for (IColumnsMapping cm : pq.getColumnsMappings()) {
            if (cm instanceof ClassColumnMappings) {
                if (cm.getSource().equals(ccm.getSource())) {
                    return (ClassColumnMappings) cm; //already exists
                }
            }
        }
        pq.addColumnsMapping(ccm);
        return ccm;
    }

    private static ClassColumnMappings addClassColumnMappings(ClassColumnMappings source, ClassColumnMappings ccm) {
        for (IColumnsMapping cm : source.getColumnsMappings()) {
            if (cm instanceof ClassColumnMappings) {
                if (cm.getSource().equals(ccm.getSource())) {
                    return (ClassColumnMappings) cm; //already exists
                }
            }
        }
        source.addColumnsMapping(ccm);
        return ccm;
    }

    public static void savePrivateProperty(DataSetDesign design, String name, String value) throws OdaException {
        if (design.getPrivateProperties() != null) {
            if (value.length() == 0 && design.getPrivateProperties().getProperty(name) == null) {
                //It seems an empty string and a null value are equal for Model 
                return;
            }
            if (!value.equals(design.getPrivateProperties().getProperty(name))) {
                design.getPrivateProperties().setProperty(name, value);
            }
        } else {
            java.util.Properties p = new java.util.Properties();
            p.put(name, value);
            design.setPrivateProperties(DesignSessionUtil.createDataSetNonPublicProperties(
                    design.getOdaExtensionDataSourceId(), design.getOdaExtensionDataSetId(), p));
        }
    }

    public static String getPrivateProperty(DataSetDesign design, String name) {
        if (design.getPrivateProperties() != null) {
            return design.getPrivateProperties().getProperty(name);
        }
        return null;
    }

    public static String getPublicProperty(DataSourceDesign ds, String name) {
        if (ds.getPublicProperties() != null) {
            return ds.getPublicProperties().getProperty(name);
        }
        return null;
    }

    public static String getPrivateProperty(DataSourceDesign ds, String name) {
        if (ds.getPrivateProperties() != null) {
            return ds.getPrivateProperties().getProperty(name);
        }
        return null;
    }

    public static IMappingSource[] getMappingSource(String mappingPath) throws OdaException {
        assert mappingPath != null;

        String[] mappingParts = splitBy(mappingPath, Constants.METHOD_OR_FIELD_SEPARATOR);
        if (mappingParts == null) {
            throw new OdaException(Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                    new Object[] { mappingPath }));
        }
        List<IMappingSource> sources = new ArrayList<IMappingSource>();
        for (String mappingPart : mappingParts) {
            String part = mappingPart.trim();
            if (part.equals("")) //$NON-NLS-1$
            {
                throw new OdaException(Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                        new Object[] { mappingPath }));
            }
            if (part.matches(METHOD_FLAG)) //Maybe a valid method
            {
                int last = part.lastIndexOf('(');
                String methodName = part.substring(0, last).trim();
                if (isValidIdentifier(methodName)) {
                    String paramParts = part.substring(last + 1, part.length() - 1).trim();
                    List<IMethodParameter> params = new ArrayList<IMethodParameter>();
                    if (paramParts.length() > 0) //contain parameters
                    {
                        String[] ps = splitBy(paramParts, Constants.METHOD_PARAM_SEPARATOR);
                        if (ps == null) {
                            throw new OdaException(Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                                    new Object[] { mappingPath }));
                        }
                        for (String p : ps) {
                            String param = p.trim();
                            if (param.length() == 0) {
                                throw new OdaException(
                                        Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                                                new Object[] { mappingPath }));
                            }
                            String[] nameOrValueAndType = splitBy(param, Constants.PARAM_TYPE_SEPARATOR);
                            if (nameOrValueAndType == null
                                    || !(nameOrValueAndType.length == 1 || nameOrValueAndType.length == 2)) {
                                throw new OdaException(
                                        Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                                                new Object[] { mappingPath }));
                            }
                            if (nameOrValueAndType.length == 1) {
                                String type = nameOrValueAndType[0].trim();
                                if (type.length() == 0) {
                                    throw new OdaException(
                                            Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                                                    new Object[] { mappingPath }));
                                }
                                params.add(new ConstantParameter(null, type));
                            } else {
                                //nameOrValueAndType.length == 2
                                String nameOrValue = nameOrValueAndType[0].trim();
                                String type = nameOrValueAndType[1].trim();
                                if (nameOrValue.length() == 0 || type.length() == 0) {
                                    throw new OdaException(
                                            Messages.getFormattedString("DataSet.InvalidColumnMappingPath", //$NON-NLS-1$
                                                    new Object[] { mappingPath }));
                                }
                                if (nameOrValue.startsWith(String.valueOf(Constants.CONSTANT_PARAM_VALUE_QUOTE))
                                        && nameOrValue
                                                .endsWith(String.valueOf(Constants.CONSTANT_PARAM_VALUE_QUOTE))) {
                                    String value = nameOrValue.substring(1, nameOrValue.length() - 1);
                                    String regex = "\\Q" + Constants.CONSTANT_PARAM_VALUE_QUOTE_ESCAPE //$NON-NLS-1$
                                            + Constants.CONSTANT_PARAM_VALUE_QUOTE + "\\E"; //$NON-NLS-1$

                                    //skip all escape chars
                                    value = value.replaceAll(regex,
                                            String.valueOf(Constants.CONSTANT_PARAM_VALUE_QUOTE));
                                    params.add(new ConstantParameter(value, type));
                                } else {
                                    params.add(new VariableParameter(nameOrValue, type));
                                }
                            }
                        }
                    }
                    sources.add(new MethodSource(methodName, params.toArray(new IMethodParameter[0])));
                } else {
                    throw new OdaException(Messages.getFormattedString("DataSet.InvalidMethodName", //$NON-NLS-1$
                            new Object[] { methodName }));
                }
            } else if (isValidIdentifier(part))// 
            {
                sources.add(new FieldSource(part));
            } else {
                throw new OdaException(Messages.getFormattedString("DataSet.InvalidFieldName", //$NON-NLS-1$
                        new Object[] { part }));
            }
        }
        return sources.toArray(new IMappingSource[0]);
    }

    public static boolean isEmptyString(String s) {
        return s == null || s.trim().length() == 0;
    }

    /**
     * we should consider the case that char <parameter>separator</parameter> included in a quoted string 
     * @param s: string to be split
     * @param separator: can not be <code>CONSTANT_PARAM_VALUE_QUOTE</code> or <code>CONSTANT_PARAM_VALUE_QUOTE_ESCAPE</code>
     * @return null if " numbers in <parameter>s</parameter> are not matched
     */
    private static String[] splitBy(String s, char separator) throws OdaException {
        assert s != null;
        List<String> result = new ArrayList<String>();
        int startIndex = 0;
        int curIndex = 0;
        boolean isWaitingForEndQuote = false;
        while (curIndex < s.length()) {
            char c = s.charAt(curIndex);
            if (isWaitingForEndQuote) {
                if (c == Constants.CONSTANT_PARAM_VALUE_QUOTE
                        && s.charAt(curIndex - 1) != Constants.CONSTANT_PARAM_VALUE_QUOTE_ESCAPE) //not an escape case
                {
                    //go to the end of a quoted string
                    isWaitingForEndQuote = false;
                }
            } else {
                if (c == separator) {
                    result.add(s.substring(startIndex, curIndex));
                    startIndex = curIndex + 1;
                } else if (c == Constants.CONSTANT_PARAM_VALUE_QUOTE) {
                    isWaitingForEndQuote = true;
                }
            }
            curIndex++;
        }
        if (isWaitingForEndQuote) //" numbers in s are not matched
        {
            return null;
        }
        result.add(s.substring(startIndex, curIndex));
        return result.toArray(new String[0]);
    }

    private static boolean isValidIdentifier(String s) {
        assert s.length() > 0;
        char[] chars = s.toCharArray();
        if (!Character.isJavaIdentifierStart(chars[0])) {
            return false;
        }
        for (int i = 1; i < chars.length; i++) {
            if (!Character.isJavaIdentifierPart(chars[i])) {
                return false;
            }
        }
        return true;
    }

    public static class FileComparator implements Comparator<File>, Serializable {
        private static final long serialVersionUID = 1L;

        public int compare(File o1, File o2) {
            if (o1.isDirectory() && o2.isDirectory()) {
                return o1.getName().compareTo(o2.getName());
            } else if (o1.isFile() && o2.isFile()) {
                return o1.getName().compareTo(o2.getName());
            } else if (o1.isDirectory() && !o2.isDirectory()) {
                return -1;
            } else {
                //o1 is not a directory but o2 is a directory
                return 1;
            }
        }
    }

    public static void savePojoQuery(PojoQuery pq, DataSetDesign design, Shell shell) {
        try {
            design.setQueryText(PojoQueryWriter.write(pq));
        } catch (OdaException e) {
            ExceptionHandler.showException(shell, Messages.getString("DataSet.FailedToSaveTitle"), //$NON-NLS-1$
                    Messages.getString("DataSet.FailedToSaveMsg"), e); //$NON-NLS-1$
        }
    }

    public static boolean isColumnDefinitionsEqual(PojoQuery pq, ColumnDefinition[] cds) {
        try {
            return Arrays.equals(Utils.getColumnDefinitions(pq), cds);
        } catch (OdaException e) {
            logger.log(Level.WARNING, "Failed to get column definitions from pq", e); //$NON-NLS-1$
            return false;
        }
    }

    public static Image getClassFlagImg() {
        return JFaceResources.getImageRegistry().get(CLASS_IMG_FLAG);
    }

    public static Image getFieldFlagImg() {
        return JFaceResources.getImageRegistry().get(FIELD_IMG_FLAG);
    }

    public static Image getMethodFlagImg() {
        return JFaceResources.getImageRegistry().get(METHOD_IMG_FLAG);
    }

    public static Image getWarningFlagImg() {
        return JFaceResources.getImageRegistry().get(WARNING_IMG_FLAG);
    }

    public static Image getFolderIcon() {
        return JFaceResources.getImageRegistry().get(FOLDER_ICON);
    }

    public static Image getJarIcon() {
        return JFaceResources.getImageRegistry().get(JAR_ICON);
    }

    public static Image getOKIcon() {
        return JFaceResources.getImageRegistry().get(OK_DISABLE_ICON);
    }

    public static Image getFailIcon() {
        return JFaceResources.getImageRegistry().get(FAIL_DISABLE_ICON);
    }

}