blob: 7087ad808cee833c143cebe0939059f3e4c74666 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2016, 2017 EfficiOS Inc. and others
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
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 3.2
*/
public final class TmfViewFactory {
/**
* The separator used for secondary id internal use. This allows 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 exists 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[&uuid]|:uuid]
* @param generateSuffix
* Add or replace a generated suffix id (UUID). This allows
* multiple views with the same id to be displayed.
* @return The view instance, or null if an error occurred.
*/
@NonNullByDefault
public static @Nullable IViewPart newView(String viewId, boolean generateSuffix) {
IViewPart viewPart = null;
String primaryId = null;
String secondaryId = null;
/* Parse the view id */
int index = viewId.indexOf(TmfView.VIEW_ID_SEPARATOR);
if (index != -1) {
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 The base secondary id excluding the UUID, or null when the passed
* string is a UUID.
*/
public static @Nullable String getBaseSecId(String secId) {
if (secId == null) {
return null;
}
int uuidSeparator = secId.lastIndexOf(INTERNAL_SECONDARY_ID_SEPARATOR);
if (uuidSeparator == -1) {
if (isUUID(secId)) {
return null;
}
return secId;
}
/**
* 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(uuidSeparator + 1);
if (!isUUID(potentialUUID)) {
return secId;
}
return secId.substring(0, uuidSeparator);
}
/**
* 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;
}
}
}