1 /*
   2  * Copyright (c) 2008, 2015, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 package ensemble.samplepage;
  33 
  34 import ensemble.Page;
  35 import ensemble.PageBrowser;
  36 import ensemble.SampleInfo;
  37 import static ensemble.SampleInfo.SampleRuntimeInfo;
  38 
  39 import javafx.beans.binding.ObjectBinding;
  40 import javafx.beans.binding.StringBinding;
  41 import javafx.beans.property.ObjectProperty;
  42 import javafx.beans.property.ReadOnlyStringProperty;
  43 import javafx.beans.property.SimpleObjectProperty;
  44 import javafx.beans.property.SimpleStringProperty;
  45 import javafx.beans.property.StringProperty;
  46 import javafx.beans.value.ChangeListener;
  47 import javafx.beans.value.ObservableValue;
  48 import javafx.scene.Node;
  49 import javafx.scene.layout.StackPane;
  50 import javafx.util.Callback;
  51 
  52 /**
  53  * Page for showing a sample
  54  */
  55 public class SamplePage extends StackPane implements Page {
  56     static final double INDENT = 8;
  57     final ObjectProperty<SampleInfo> sampleInfoProperty = new SimpleObjectProperty<>();
  58     private final StringProperty titleProperty = new SimpleStringProperty();
  59     PageBrowser pageBrowser;
  60     final ObjectProperty<SampleRuntimeInfo> sampleRuntimeInfoProperty = new SimpleObjectProperty<>();
  61 
  62     public SamplePage(SampleInfo sampleInfo, String url, final PageBrowser pageBrowser) {
  63         sampleInfoProperty.set(sampleInfo);
  64         this.pageBrowser = pageBrowser;
  65         getStyleClass().add("sample-page");
  66         titleProperty.bind(new StringBinding() {
  67             { bind(sampleInfoProperty); }
  68             @Override protected String computeValue() {
  69                 SampleInfo sample = SamplePage.this.sampleInfoProperty.get();
  70                 if (sample != null) {
  71                     return sample.name;
  72                 } else {
  73                     return null;
  74                 }
  75             }
  76         });
  77         sampleRuntimeInfoProperty.bind(new ObjectBinding<SampleRuntimeInfo>() {
  78             { bind(sampleInfoProperty); }
  79             @Override protected SampleRuntimeInfo computeValue() {
  80                 return sampleInfoProperty.get().buildSampleNode();
  81             }
  82         });
  83 
  84         SamplePageContent frontPage = new SamplePageContent(this);
  85         getChildren().setAll(frontPage);
  86     }
  87 
  88     public void update(SampleInfo sampleInfo, String url) {
  89         sampleInfoProperty.set(sampleInfo);
  90     }
  91 
  92     @Override public ReadOnlyStringProperty titleProperty() {
  93         return titleProperty;
  94     }
  95 
  96     @Override public String getTitle() {
  97         return titleProperty.get();
  98     }
  99 
 100     @Override public String getUrl() {
 101         return "sample://" + sampleInfoProperty.get().ensemblePath;
 102     }
 103 
 104     @Override public Node getNode() {
 105         return this;
 106     }
 107     
 108     String apiClassToUrl(String classname) {
 109         String urlEnd = classname.replaceAll("\\.([a-z])", "/$1").replaceFirst("\\.([A-Z])", "/$1");
 110         if (classname.startsWith("javafx")) {
 111             return "https://docs.oracle.com/javase/8/javafx/api/"+urlEnd+".html";
 112         } else {
 113             return "https://docs.oracle.com/javase/8/docs/api/"+urlEnd+".html";
 114         }
 115     }
 116 
 117     /**
 118      * This method is equivalent to bind(ObjectBinding) as it would invoke
 119      * updater immediately as well as on any change to SampleInfo
 120      * @param updater a method that updates content for a given SampleInfo
 121      */
 122     void registerSampleInfoUpdater(final Callback<SampleInfo, Void> updater) {
 123         sampleInfoProperty.addListener((ObservableValue<? extends SampleInfo> ov, SampleInfo t, SampleInfo sampleInfo) -> {
 124             updater.call(sampleInfo);
 125         });
 126         updater.call(sampleInfoProperty.get());
 127     }
 128 }