Introduce "New view" action for views based on TmfView
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / TmfViewFactory.java
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfViewFactory.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/TmfViewFactory.java
new file mode 100644 (file)
index 0000000..cc2ee13
--- /dev/null
@@ -0,0 +1,169 @@
+/**********************************************************************
+ * Copyright (c) 2016 EfficiOS 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
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.views;
+
+import java.util.UUID;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Factory for TmfView.
+ *
+ * @author Jonathan Rajotte Julien
+ * @since 2.2
+ */
+public final class TmfViewFactory {
+
+    /**
+     * The separator used for secondary id internal use. This allow to have
+     * multiple level of information inside the secondary id.
+     */
+    @VisibleForTesting
+    public static final String INTERNAL_SECONDARY_ID_SEPARATOR = "&"; //$NON-NLS-1$
+
+    /**
+     * Empty constructor
+     */
+    private TmfViewFactory() {}
+
+    /**
+     * Create a new view. <br>
+     *
+     * If a view with the corresponding id already exist and no suffix were
+     * added the existing view will be given focus.
+     *
+     * @param viewId
+     *            The id of the view to be created. <br>
+     *            Format: <primary_id>[:secondary_id][&third_id]..[&n_id]
+     * @param generateSuffix
+     *            Add a generated suffix id (UUID). This allow multiple view of
+     *            the same id to be displayed.
+     * @return
+     *          NULL if an error occurred.
+     *          The view instance.
+     */
+    @NonNullByDefault
+    public static @Nullable IViewPart newView(String viewId, boolean generateSuffix) {
+        IViewPart viewPart = null;
+        String primaryId = null;
+        String secondaryId = null;
+
+        /* Parse the view id */
+        if (viewId.contains(TmfView.PRIMARY_SECONDARY_ID_SEPARATOR)) {
+            int index = viewId.indexOf(TmfView.PRIMARY_SECONDARY_ID_SEPARATOR);
+
+            primaryId = viewId.substring(0, index);
+            secondaryId = getBaseSecId(viewId.substring(index + 1));
+
+        } else {
+            primaryId = viewId;
+        }
+
+        if (generateSuffix) {
+            if (secondaryId == null) {
+                secondaryId = UUID.randomUUID().toString();
+            } else {
+                secondaryId += INTERNAL_SECONDARY_ID_SEPARATOR + UUID.randomUUID().toString();
+            }
+        }
+
+        IWorkbench workbench = PlatformUI.getWorkbench();
+        IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
+        IWorkbenchPage page = workbenchWindow.getActivePage();
+        try {
+            viewPart = page.showView(primaryId, secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
+            page.activate(viewPart);
+        } catch (PartInitException e) {
+            /* Simply return null on error */
+        }
+
+        return viewPart;
+    }
+
+    /**
+     * Parse a secondary id and return the base secondary id minus any generated
+     * suffix (UUID).
+     *
+     * @param secId
+     *            A view secondary id
+     * @return NULL when the passed string is a UUID. <br>
+     *         The base secondary id
+     */
+    public static String getBaseSecId(String secId) {
+        if (secId == null) {
+            return null;
+        }
+
+        if (!secId.contains(INTERNAL_SECONDARY_ID_SEPARATOR)) {
+            if (isUUID(secId)) {
+                return null;
+            }
+            return secId;
+        }
+
+        int lastIndexSepartor = secId.lastIndexOf(INTERNAL_SECONDARY_ID_SEPARATOR);
+
+        /**
+         * Validate that the right side of the separator is a UUID since the
+         * separator could be a valid value from the base secondary id.
+         */
+        String potentialUUID = secId.substring(lastIndexSepartor + 1);
+
+        if (!isUUID(potentialUUID)) {
+            return secId;
+        }
+
+        return secId.substring(0, lastIndexSepartor);
+    }
+
+    /**
+     * Utility method for testing if a string is a valid full length UUID.
+     * <br>
+     * <pre>
+     * e.g:
+     *     9eaf1840-8a87-4314-a8b7-03e3eccf4766 -> true
+     *     1-1-1-1-1 -> false
+     * </pre>
+     *
+     * @param uuid
+     *            The string to test
+     * @return If the passed string is a UUID
+     */
+    private static boolean isUUID(String uuid) {
+        if (uuid == null) {
+            return false;
+        }
+
+        try {
+            /*
+             * UUID.fromString does not check for length wise valid UUID only the
+             * UUID form so check if the reverse operation is valid.
+             */
+            UUID fromStringUUID = UUID.fromString(uuid);
+            String toStringUUID = fromStringUUID.toString();
+            return toStringUUID.equals(uuid);
+        } catch (IllegalArgumentException e) {
+            /**
+             * The substring is not a UUID. Assume that the separator come from
+             * the initial secondaryId.
+             */
+             return false;
+        }
+    }
+}
This page took 0.025288 seconds and 5 git commands to generate.