javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/KOList.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 15 Apr 2013 22:03:59 +0200
branchfx
changeset 993 08e7b312664f
parent 987 5d8eea9d2831
permissions -rw-r--r--
Disable logging - Twttr Client works, so why continue to log?
jaroslav@761
     1
/**
jaroslav@761
     2
 * Back 2 Browser Bytecode Translator
jaroslav@761
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@761
     4
 *
jaroslav@761
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@761
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@761
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@761
     8
 *
jaroslav@761
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@761
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@761
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@761
    12
 * GNU General Public License for more details.
jaroslav@761
    13
 *
jaroslav@761
    14
 * You should have received a copy of the GNU General Public License
jaroslav@761
    15
 * along with this program. Look for COPYING file in the top folder.
jaroslav@761
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
jaroslav@761
    17
 */
jaroslav@761
    18
package org.apidesign.bck2brwsr.htmlpage;
jaroslav@761
    19
jaroslav@976
    20
import java.lang.reflect.InvocationTargetException;
jaroslav@976
    21
import java.lang.reflect.Method;
jaroslav@761
    22
import java.util.ArrayList;
jaroslav@761
    23
import java.util.Collection;
jaroslav@921
    24
import java.util.Iterator;
jaroslav@976
    25
import java.util.logging.Level;
jaroslav@976
    26
import java.util.logging.Logger;
jaroslav@887
    27
import org.apidesign.bck2brwsr.core.JavaScriptOnly;
jaroslav@761
    28
jaroslav@761
    29
/**
jaroslav@761
    30
 *
jaroslav@761
    31
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@761
    32
 */
jaroslav@761
    33
public final class KOList<T> extends ArrayList<T> {
jaroslav@761
    34
    private final String name;
jaroslav@761
    35
    private final String[] deps;
jaroslav@761
    36
    private Knockout model;
jaroslav@950
    37
    private Runnable onchange;
jaroslav@761
    38
jaroslav@761
    39
    public KOList(String name, String... deps) {
jaroslav@761
    40
        this.name = name;
jaroslav@761
    41
        this.deps = deps;
jaroslav@761
    42
    }
jaroslav@761
    43
    
jaroslav@761
    44
    public void assign(Knockout model) {
jaroslav@955
    45
        if (this.model != model) {
jaroslav@955
    46
            this.model = model;
jaroslav@955
    47
            notifyChange();
jaroslav@955
    48
        }
jaroslav@761
    49
    }
jaroslav@950
    50
    
jaroslav@950
    51
    public KOList<T> onChange(Runnable r) {
jaroslav@950
    52
        if (this.onchange != null) {
jaroslav@950
    53
            throw new IllegalStateException();
jaroslav@950
    54
        }
jaroslav@950
    55
        this.onchange = r;
jaroslav@950
    56
        return this;
jaroslav@950
    57
    }
jaroslav@761
    58
jaroslav@761
    59
    @Override
jaroslav@761
    60
    public boolean add(T e) {
jaroslav@761
    61
        boolean ret = super.add(e);
jaroslav@761
    62
        notifyChange();
jaroslav@761
    63
        return ret;
jaroslav@761
    64
    }
jaroslav@761
    65
jaroslav@761
    66
    @Override
jaroslav@928
    67
    public boolean addAll(Collection<? extends T> c) {
jaroslav@928
    68
        boolean ret = super.addAll(c);
jaroslav@928
    69
        notifyChange();
jaroslav@928
    70
        return ret;
jaroslav@928
    71
    }
jaroslav@928
    72
jaroslav@928
    73
    @Override
jaroslav@928
    74
    public boolean addAll(int index, Collection<? extends T> c) {
jaroslav@928
    75
        boolean ret = super.addAll(index, c);
jaroslav@928
    76
        notifyChange();
jaroslav@928
    77
        return ret;
jaroslav@928
    78
    }
jaroslav@928
    79
jaroslav@928
    80
    @Override
jaroslav@761
    81
    public boolean remove(Object o) {
jaroslav@761
    82
        boolean ret = super.remove(o);
jaroslav@761
    83
        notifyChange();
jaroslav@761
    84
        return ret;
jaroslav@761
    85
    }
jaroslav@761
    86
jaroslav@761
    87
    @Override
jaroslav@761
    88
    public void clear() {
jaroslav@761
    89
        super.clear();
jaroslav@761
    90
        notifyChange();
jaroslav@761
    91
    }
jaroslav@761
    92
jaroslav@761
    93
    @Override
jaroslav@761
    94
    public boolean removeAll(Collection<?> c) {
jaroslav@761
    95
        boolean ret = super.removeAll(c);
jaroslav@761
    96
        notifyChange();
jaroslav@761
    97
        return ret;
jaroslav@761
    98
    }
jaroslav@761
    99
jaroslav@761
   100
    @Override
jaroslav@761
   101
    public boolean retainAll(Collection<?> c) {
jaroslav@761
   102
        boolean ret = super.retainAll(c);
jaroslav@761
   103
        notifyChange();
jaroslav@761
   104
        return ret;
jaroslav@761
   105
    }
jaroslav@761
   106
jaroslav@761
   107
    @Override
jaroslav@761
   108
    public T set(int index, T element) {
jaroslav@761
   109
        T ret = super.set(index, element);
jaroslav@761
   110
        notifyChange();
jaroslav@761
   111
        return ret;
jaroslav@761
   112
    }
jaroslav@761
   113
jaroslav@761
   114
    @Override
jaroslav@761
   115
    public void add(int index, T element) {
jaroslav@761
   116
        super.add(index, element);
jaroslav@761
   117
        notifyChange();
jaroslav@761
   118
    }
jaroslav@761
   119
jaroslav@761
   120
    @Override
jaroslav@761
   121
    public T remove(int index) {
jaroslav@761
   122
        T ret = super.remove(index);
jaroslav@761
   123
        notifyChange();
jaroslav@761
   124
        return ret;
jaroslav@761
   125
    }
jaroslav@921
   126
jaroslav@921
   127
    @Override
jaroslav@921
   128
    public String toString() {
jaroslav@921
   129
        Iterator<T> it = iterator();
jaroslav@921
   130
        if (!it.hasNext()) {
jaroslav@921
   131
            return "[]";
jaroslav@921
   132
        }
jaroslav@921
   133
        String sep = "";
jaroslav@921
   134
        StringBuilder sb = new StringBuilder();
jaroslav@921
   135
        sb.append('[');
jaroslav@921
   136
        while (it.hasNext()) {
jaroslav@921
   137
            T t = it.next();
jaroslav@921
   138
            sb.append(sep);
jaroslav@921
   139
            sb.append(ConvertTypes.toJSON(t));
jaroslav@921
   140
            sep = ",";
jaroslav@921
   141
        }
jaroslav@921
   142
        sb.append(']');
jaroslav@921
   143
        return sb.toString();
jaroslav@921
   144
    }
jaroslav@887
   145
    
jaroslav@887
   146
    
jaroslav@887
   147
    @JavaScriptOnly(name = "koArray", value = "function() { return this.toArray___3Ljava_lang_Object_2(); }")
jaroslav@887
   148
    private static native int koArray();
jaroslav@971
   149
    
jaroslav@971
   150
    public Object koData() {
jaroslav@976
   151
        Object[] arr = toArray();
jaroslav@976
   152
        Method toKO = null;
jaroslav@976
   153
        for (int i = 0; i < arr.length; i++) {
jaroslav@976
   154
            if (arr[i] == null) {
jaroslav@976
   155
                continue;
jaroslav@976
   156
            }
jaroslav@976
   157
            if (toKO == null || toKO.getDeclaringClass() != arr[i].getClass()) {
jaroslav@976
   158
                try {
jaroslav@976
   159
                    toKO = arr[i].getClass().getDeclaredMethod("koData");
jaroslav@976
   160
                    toKO.setAccessible(true);
jaroslav@976
   161
                } catch (NoSuchMethodException ex) {
jaroslav@976
   162
                    LOG.log(Level.FINE, "No koData conversion for " + arr[i], ex);
jaroslav@976
   163
                    toKO = null;
jaroslav@976
   164
                }
jaroslav@976
   165
            }
jaroslav@976
   166
            if (toKO != null) {
jaroslav@976
   167
                try {
jaroslav@979
   168
                    Object prev = arr[i];
jaroslav@976
   169
                    arr[i] = toKO.invoke(arr[i]);
jaroslav@993
   170
                    LOG.log(Level.FINER, "{0}th element {1} replaced by {2}", new Object[]{i, prev, arr[i]});
jaroslav@976
   171
                } catch (IllegalAccessException | InvocationTargetException ex) {
jaroslav@976
   172
                    LOG.log(Level.SEVERE, "Problems invoking koData on " + arr[i], ex);
jaroslav@976
   173
                }
jaroslav@976
   174
            }
jaroslav@976
   175
        }
jaroslav@987
   176
        return Knockout.toArray(arr);
jaroslav@971
   177
    }
jaroslav@976
   178
    private static final Logger LOG = Logger.getLogger(KOList.class.getName());
jaroslav@761
   179
jaroslav@761
   180
    private void notifyChange() {
jaroslav@761
   181
        Knockout m = model;
jaroslav@950
   182
        if (m != null) {
jaroslav@950
   183
            m.valueHasMutated(name);
jaroslav@950
   184
            for (String dependant : deps) {
jaroslav@950
   185
                m.valueHasMutated(dependant);
jaroslav@950
   186
            }
jaroslav@761
   187
        }
jaroslav@950
   188
        Runnable r = onchange;
jaroslav@950
   189
        if (r != null) {
jaroslav@950
   190
            r.run();
jaroslav@761
   191
        }
jaroslav@761
   192
    }
jaroslav@930
   193
jaroslav@930
   194
    @Override
jaroslav@930
   195
    public KOList clone() {
jaroslav@955
   196
        KOList ko = (KOList)super.clone();
jaroslav@955
   197
        ko.model = null;
jaroslav@955
   198
        return ko;
jaroslav@930
   199
    }
jaroslav@761
   200
    
jaroslav@761
   201
}