1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * 
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * The contents of this file are subject to the terms of either the Universal Permissive License
   7  * v 1.0 as shown at http://oss.oracle.com/licenses/upl
   8  *
   9  * or the following license:
  10  *
  11  * Redistribution and use in source and binary forms, with or without modification, are permitted
  12  * provided that the following conditions are met:
  13  * 
  14  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions
  15  * and the following disclaimer.
  16  * 
  17  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
  18  * conditions and the following disclaimer in the documentation and/or other materials provided with
  19  * the distribution.
  20  * 
  21  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
  22  * endorse or promote products derived from this software without specific prior written permission.
  23  * 
  24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  26  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
  31  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 package org.openjdk.jmc.flightrecorder.ui;
  34 
  35 import java.util.ArrayList;
  36 import java.util.List;
  37 
  38 import org.eclipse.core.runtime.Platform;
  39 import org.eclipse.jface.resource.ImageDescriptor;
  40 import org.openjdk.jmc.common.IState;
  41 import org.openjdk.jmc.common.IStateful;
  42 import org.openjdk.jmc.common.util.StatefulState;
  43 
  44 /**
  45  * A page descriptor. Contains description, state and children for a page. It is intended to be used
  46  * for holding information about a page that is relevant on a process global level. When a page is
  47  * to be shown it is converted to a {@link IDisplayablePage} which is held on a recording level
  48  * (i.e., one instance per open recording).
  49  */
  50 public class DataPageDescriptor implements IPageDefinition {
  51 
  52         private StatefulState pageState;
  53         private final String id;
  54         private final String factoryId;
  55         private final IDataPageFactory factory;
  56 
  57         private DataPageDescriptor parent = null;
  58         private final List<DataPageDescriptor> children = new ArrayList<>();
  59 
  60         DataPageDescriptor(DataPageDescriptor source) {
  61                 this(source.id, source.factoryId, source.factory, source.pageState);
  62         }
  63 
  64         DataPageDescriptor(String id, String factoryId, IDataPageFactory factory, StatefulState pageState) {
  65                 this.id = id;
  66                 this.factoryId = factoryId;
  67                 this.factory = factory;
  68                 setPageState(pageState);
  69         }
  70 
  71         String getId() {
  72                 return id;
  73         }
  74 
  75         String getFactoryId() {
  76                 return factoryId;
  77         }
  78 
  79         String getHelpContextId() {
  80                 // FIXME: Somehow determine that page id should not be used as help context id (e.g. for generated pages)
  81                 int index = id.lastIndexOf('.');
  82                 // The help system will interpret the help context id as pluginId.contextId
  83                 if (index != -1 && Platform.getBundle(id.substring(0, index)) != null) {
  84                         return id;
  85                 }
  86                 return factoryId;
  87         }
  88 
  89         void setPageState(StatefulState state) {
  90                 if (state == null) {
  91                         pageState = StatefulState.create(writableState -> factory.resetToDefault(pageState, writableState));
  92                 } else {
  93                         pageState = state;
  94                 }
  95         }
  96 
  97         DataPageDescriptor getParent() {
  98                 return parent;
  99         }
 100 
 101         // Should only be called from PageManager
 102         void setParent(DataPageDescriptor parent) {
 103                 this.parent = parent;
 104         }
 105 
 106         // Should only be called from PageManager as the list is mutable
 107         List<DataPageDescriptor> getChildList() {
 108                 return children;
 109         }
 110 
 111         public boolean hasChildren() {
 112                 return children.size() > 0;
 113         }
 114 
 115         public DataPageDescriptor[] getChildren() {
 116                 return children.toArray(new DataPageDescriptor[children.size()]);
 117         }
 118 
 119         boolean contains(DataPageDescriptor dpd) {
 120                 return dpd == this || (dpd.parent != null && contains(dpd.parent));
 121         }
 122 
 123         @Override
 124         public IState getState() {
 125                 return getPageState();
 126         }
 127 
 128         StatefulState getPageState() {
 129                 return pageState;
 130         }
 131 
 132         void readPageStateFrom(IStateful page) {
 133                 pageState = StatefulState.create(page);
 134         }
 135 
 136         IDisplayablePage createPage(StreamModel items, IPageContainer editor) {
 137                 return factory.createPage(this, items, editor);
 138         }
 139 
 140         @Override
 141         public String getName() {
 142                 return factory.getName(pageState);
 143         }
 144 
 145         @Override
 146         public String getDescription() {
 147                 return factory.getDescription(pageState);
 148         }
 149 
 150         @Override
 151         public String[] getTopics() {
 152                 return factory.getTopics(pageState);
 153         }
 154 
 155         @Override
 156         public ImageDescriptor getImageDescriptor() {
 157                 return factory.getImageDescriptor(pageState);
 158         }
 159         
 160         @Override
 161         public String toString() {
 162                 return getId() + " children:" + String.valueOf(children); //$NON-NLS-1$
 163         }
 164 }