ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/KOList.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 29 Apr 2013 12:50:19 +0200
changeset 1189 9f8b07dcbe79
permissions -rw-r--r--
Putting the bck2brwsr bindings into html.java.net repository
     1 /**
     2  * HTML via Java(tm) Language Bindings
     3  * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details. apidesign.org
    13  * designates this particular file as subject to the
    14  * "Classpath" exception as provided by apidesign.org
    15  * in the License file that accompanied this code.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program. Look for COPYING file in the top folder.
    19  * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
    20  */
    21 package org.apidesign.html.ko2brwsr;
    22 
    23 import java.util.ArrayList;
    24 import java.util.Collection;
    25 import java.util.Iterator;
    26 import org.apidesign.bck2brwsr.core.JavaScriptOnly;
    27 
    28 /**
    29  *
    30  * @author Jaroslav Tulach <jtulach@netbeans.org>
    31  */
    32 public final class KOList<T> extends ArrayList<T> {
    33     private final String name;
    34     private final String[] deps;
    35     private Knockout model;
    36     private Runnable onchange;
    37 
    38     public KOList(String name, String... deps) {
    39         this.name = name;
    40         this.deps = deps;
    41     }
    42     
    43     public void assign(Knockout model) {
    44         if (this.model != model) {
    45             this.model = model;
    46             notifyChange();
    47         }
    48     }
    49     
    50     public KOList<T> onChange(Runnable r) {
    51         if (this.onchange != null) {
    52             throw new IllegalStateException();
    53         }
    54         this.onchange = r;
    55         return this;
    56     }
    57 
    58     @Override
    59     public boolean add(T e) {
    60         boolean ret = super.add(e);
    61         notifyChange();
    62         return ret;
    63     }
    64 
    65     @Override
    66     public boolean addAll(Collection<? extends T> c) {
    67         boolean ret = super.addAll(c);
    68         notifyChange();
    69         return ret;
    70     }
    71 
    72     @Override
    73     public boolean addAll(int index, Collection<? extends T> c) {
    74         boolean ret = super.addAll(index, c);
    75         notifyChange();
    76         return ret;
    77     }
    78 
    79     @Override
    80     public boolean remove(Object o) {
    81         boolean ret = super.remove(o);
    82         notifyChange();
    83         return ret;
    84     }
    85 
    86     @Override
    87     public void clear() {
    88         super.clear();
    89         notifyChange();
    90     }
    91 
    92     @Override
    93     public boolean removeAll(Collection<?> c) {
    94         boolean ret = super.removeAll(c);
    95         notifyChange();
    96         return ret;
    97     }
    98 
    99     @Override
   100     public boolean retainAll(Collection<?> c) {
   101         boolean ret = super.retainAll(c);
   102         notifyChange();
   103         return ret;
   104     }
   105 
   106     @Override
   107     public T set(int index, T element) {
   108         T ret = super.set(index, element);
   109         notifyChange();
   110         return ret;
   111     }
   112 
   113     @Override
   114     public void add(int index, T element) {
   115         super.add(index, element);
   116         notifyChange();
   117     }
   118 
   119     @Override
   120     public T remove(int index) {
   121         T ret = super.remove(index);
   122         notifyChange();
   123         return ret;
   124     }
   125 
   126     @Override
   127     public String toString() {
   128         Iterator<T> it = iterator();
   129         if (!it.hasNext()) {
   130             return "[]";
   131         }
   132         String sep = "";
   133         StringBuilder sb = new StringBuilder();
   134         sb.append('[');
   135         while (it.hasNext()) {
   136             T t = it.next();
   137             sb.append(sep);
   138             sb.append(ConvertTypes.toJSON(t));
   139             sep = ",";
   140         }
   141         sb.append(']');
   142         return sb.toString();
   143     }
   144     
   145     
   146     @JavaScriptOnly(name = "koArray", value = "function() { return this.toArray___3Ljava_lang_Object_2(); }")
   147     private static native int koArray();
   148 
   149     private void notifyChange() {
   150         Knockout m = model;
   151         if (m != null) {
   152             m.valueHasMutated(name);
   153             for (String dependant : deps) {
   154                 m.valueHasMutated(dependant);
   155             }
   156         }
   157         Runnable r = onchange;
   158         if (r != null) {
   159             r.run();
   160         }
   161     }
   162 
   163     @Override
   164     public KOList clone() {
   165         KOList ko = (KOList)super.clone();
   166         ko.model = null;
   167         return ko;
   168     }
   169     
   170 }