1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Observers.java Sat Aug 02 06:41:59 2014 +0200
1.3 @@ -0,0 +1,226 @@
1.4 +/**
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 + *
1.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
1.8 + *
1.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
1.10 + * Other names may be trademarks of their respective owners.
1.11 + *
1.12 + * The contents of this file are subject to the terms of either the GNU
1.13 + * General Public License Version 2 only ("GPL") or the Common
1.14 + * Development and Distribution License("CDDL") (collectively, the
1.15 + * "License"). You may not use this file except in compliance with the
1.16 + * License. You can obtain a copy of the License at
1.17 + * http://www.netbeans.org/cddl-gplv2.html
1.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.19 + * specific language governing permissions and limitations under the
1.20 + * License. When distributing the software, include this License Header
1.21 + * Notice in each file and include the License file at
1.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
1.23 + * particular file as subject to the "Classpath" exception as provided
1.24 + * by Oracle in the GPL Version 2 section of the License file that
1.25 + * accompanied this code. If applicable, add the following below the
1.26 + * License Header, with the fields enclosed by brackets [] replaced by
1.27 + * your own identifying information:
1.28 + * "Portions Copyrighted [year] [name of copyright owner]"
1.29 + *
1.30 + * Contributor(s):
1.31 + *
1.32 + * The Original Software is NetBeans. The Initial Developer of the Original
1.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
1.34 + *
1.35 + * If you wish your version of this file to be governed by only the CDDL
1.36 + * or only the GPL Version 2, indicate your decision by adding
1.37 + * "[Contributor] elects to include this software in this distribution
1.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
1.39 + * single choice of license, a recipient has the option to distribute
1.40 + * your version of this file under either the CDDL, the GPL Version 2 or
1.41 + * to extend the choice of license to its licensees as provided above.
1.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
1.43 + * Version 2 license, then the option applies only if the new code is
1.44 + * made subject to such option by the copyright holder.
1.45 + */
1.46 +package org.apidesign.html.json.spi;
1.47 +
1.48 +import java.lang.ref.WeakReference;
1.49 +import java.util.ArrayList;
1.50 +import java.util.Iterator;
1.51 +import java.util.LinkedList;
1.52 +import java.util.List;
1.53 +
1.54 +/**
1.55 + *
1.56 + * @author Jaroslav Tulach
1.57 + */
1.58 +final class Observers {
1.59 + private static final LinkedList<Watcher> GLOBAL = new LinkedList<Watcher>();
1.60 + private final List<Watcher> watchers = new ArrayList<Watcher>();
1.61 + private final List<Ref> observers = new ArrayList<Ref>();
1.62 +
1.63 + private Observers() {
1.64 + }
1.65 +
1.66 + static void beginComputing(Proto p, String name) {
1.67 + synchronized (GLOBAL) {
1.68 + verifyUnlocked(p);
1.69 + final Watcher nw = new Watcher(p, name);
1.70 + GLOBAL.push(nw);
1.71 + }
1.72 + }
1.73 +
1.74 + static void verifyUnlocked(Proto p) {
1.75 + synchronized (GLOBAL) {
1.76 + for (Watcher w : GLOBAL) {
1.77 + if (w.proto == p) {
1.78 + throw new IllegalStateException("Re-entrant attempt to access " + p);
1.79 + }
1.80 + }
1.81 + }
1.82 + }
1.83 +
1.84 + static Observers accessingValue(Proto p, Observers observers, String propName) {
1.85 + synchronized (GLOBAL) {
1.86 + verifyUnlocked(p);
1.87 + for (Watcher w : GLOBAL) {
1.88 + if (observers == null) {
1.89 + observers = new Observers();
1.90 + }
1.91 + observers.add(w, new Ref(w, propName));
1.92 + }
1.93 + return observers;
1.94 + }
1.95 + }
1.96 +
1.97 + static Observers finishComputing(Proto p, Observers mine) {
1.98 + synchronized (GLOBAL) {
1.99 + Watcher w = GLOBAL.pop();
1.100 + if (w.proto != p) {
1.101 + throw new IllegalStateException("Inconsistency: " + w.proto + " != " + p);
1.102 + }
1.103 + if (mine == null) {
1.104 + mine = new Observers();
1.105 + }
1.106 + mine.add(w);
1.107 + return mine;
1.108 + }
1.109 + }
1.110 +
1.111 + static Watcher computing(Proto proto, String prop) {
1.112 + proto.getClass();
1.113 + prop.getClass();
1.114 + return new Watcher(proto, prop);
1.115 + }
1.116 +
1.117 + private static final class Ref extends WeakReference<Watcher> {
1.118 + private final String prop;
1.119 +
1.120 + public Ref(Watcher ref, String prop) {
1.121 + super(ref);
1.122 + this.prop = prop;
1.123 + }
1.124 +
1.125 + final Watcher watcher() {
1.126 + Watcher w = get();
1.127 + if (w == null) {
1.128 + return null;
1.129 + }
1.130 + final Observers o = w.proto.observers();
1.131 + if (o == null) {
1.132 + return null;
1.133 + }
1.134 + if (o.find(w.prop) == w) {
1.135 + return w;
1.136 + }
1.137 + return null;
1.138 + }
1.139 + }
1.140 +
1.141 + private Watcher find(String prop) {
1.142 + if (prop == null) {
1.143 + return null;
1.144 + }
1.145 + for (Watcher w : watchers) {
1.146 + if (prop.equals(w.prop)) {
1.147 + return w;
1.148 + }
1.149 + }
1.150 + return null;
1.151 + }
1.152 +
1.153 + final void add(Watcher w) {
1.154 + for (int i = 0; i < watchers.size(); i++) {
1.155 + Watcher ith = watchers.get(i);
1.156 + if (w.prop == null) {
1.157 + if (ith.prop == null) {
1.158 + watchers.set(i, w);
1.159 + return;
1.160 + }
1.161 + } else if (w.prop.equals(ith.prop)) {
1.162 + watchers.set(i, w);
1.163 + return;
1.164 + }
1.165 + }
1.166 + watchers.add(w);
1.167 + }
1.168 +
1.169 + final void valueHasMutated(String propName) {
1.170 + List<Watcher> mutated = new LinkedList<Watcher>();
1.171 + synchronized (GLOBAL) {
1.172 + Iterator<Ref> it = observers.iterator();
1.173 + while (it.hasNext()) {
1.174 + Ref ref = it.next();
1.175 + if (ref.get() == null) {
1.176 + it.remove();
1.177 + continue;
1.178 + }
1.179 + if (ref.prop.equals(propName)) {
1.180 + Watcher w = ref.watcher();
1.181 + if (w != null) {
1.182 + mutated.add(w);
1.183 + }
1.184 + }
1.185 + }
1.186 + }
1.187 + for (Watcher w : mutated) {
1.188 + w.proto.valueHasMutated(w.prop);
1.189 + }
1.190 + }
1.191 +
1.192 + void add(Watcher w, Ref r) {
1.193 + Thread.holdsLock(GLOBAL);
1.194 + if (w == null) {
1.195 + return;
1.196 + }
1.197 + Iterator<Ref> it = observers.iterator();
1.198 + while (it.hasNext()) {
1.199 + Ref ref = it.next();
1.200 + if (r == ref) {
1.201 + return;
1.202 + }
1.203 + final Watcher rw = ref.get();
1.204 + if (rw == null) {
1.205 + it.remove();
1.206 + continue;
1.207 + }
1.208 + if (rw == w && r.prop.equals(r.prop)) {
1.209 + return;
1.210 + }
1.211 + }
1.212 + observers.add(r);
1.213 + }
1.214 +
1.215 + private static final class Watcher {
1.216 + final Proto proto;
1.217 + final String prop;
1.218 +
1.219 + Watcher(Proto proto, String prop) {
1.220 + this.proto = proto;
1.221 + this.prop = prop;
1.222 + }
1.223 +
1.224 + @Override
1.225 + public String toString() {
1.226 + return "Watcher: " + proto + ", " + prop;
1.227 + }
1.228 + }
1.229 +}
2.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Proto.java Sat Aug 02 06:25:53 2014 +0200
2.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Proto.java Sat Aug 02 06:41:59 2014 +0200
2.3 @@ -47,8 +47,6 @@
2.4 import net.java.html.BrwsrCtx;
2.5 import net.java.html.json.ComputedProperty;
2.6 import net.java.html.json.Model;
2.7 -import org.apidesign.html.json.spi.Watcher.Observers;
2.8 -import org.apidesign.html.json.spi.Watcher.Watchers;
2.9 import org.netbeans.html.json.impl.Bindings;
2.10 import org.netbeans.html.json.impl.JSON;
2.11 import org.netbeans.html.json.impl.JSONList;
2.12 @@ -71,7 +69,6 @@
2.13 private final Type type;
2.14 private final net.java.html.BrwsrCtx context;
2.15 private org.netbeans.html.json.impl.Bindings ko;
2.16 - private Watchers mine;
2.17 private Observers observers;
2.18
2.19 Proto(Object obj, Type type, BrwsrCtx context) {
2.20 @@ -97,25 +94,25 @@
2.21 acquireLock(null);
2.22 }
2.23 public void acquireLock(String propName) throws IllegalStateException {
2.24 - Watcher.beginComputing(this, propName);
2.25 + Observers.beginComputing(this, propName);
2.26 }
2.27
2.28 public void accessValue(String propName) {
2.29 - observers = Watcher.accessingValue(this, observers, propName);
2.30 + observers = Observers.accessingValue(this, observers, propName);
2.31 }
2.32
2.33 /** Verifies the model is not locked otherwise throws an exception.
2.34 * @throws IllegalStateException if the model is locked
2.35 */
2.36 public void verifyUnlocked() throws IllegalStateException {
2.37 - Watcher.verifyUnlocked(this);
2.38 + Observers.verifyUnlocked(this);
2.39 }
2.40
2.41 /** When modifications are over, the model is switched into
2.42 * unlocked state by calling this method.
2.43 */
2.44 public void releaseLock() {
2.45 - mine = Watcher.finishComputing(this, mine);
2.46 + observers = Observers.finishComputing(this, observers);
2.47 }
2.48
2.49 /** Whenever model changes a property. It should notify the
2.50 @@ -457,8 +454,8 @@
2.51 type.onChange(obj, index);
2.52 }
2.53
2.54 - final Watcher watcher(String prop) {
2.55 - return mine == null ? null : mine.find(prop);
2.56 + final Observers observers() {
2.57 + return observers;
2.58 }
2.59
2.60 /** Functionality used by the code generated by annotation
3.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Watcher.java Sat Aug 02 06:25:53 2014 +0200
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,220 +0,0 @@
3.4 -/**
3.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 - *
3.7 - * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
3.8 - *
3.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
3.10 - * Other names may be trademarks of their respective owners.
3.11 - *
3.12 - * The contents of this file are subject to the terms of either the GNU
3.13 - * General Public License Version 2 only ("GPL") or the Common
3.14 - * Development and Distribution License("CDDL") (collectively, the
3.15 - * "License"). You may not use this file except in compliance with the
3.16 - * License. You can obtain a copy of the License at
3.17 - * http://www.netbeans.org/cddl-gplv2.html
3.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.19 - * specific language governing permissions and limitations under the
3.20 - * License. When distributing the software, include this License Header
3.21 - * Notice in each file and include the License file at
3.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
3.23 - * particular file as subject to the "Classpath" exception as provided
3.24 - * by Oracle in the GPL Version 2 section of the License file that
3.25 - * accompanied this code. If applicable, add the following below the
3.26 - * License Header, with the fields enclosed by brackets [] replaced by
3.27 - * your own identifying information:
3.28 - * "Portions Copyrighted [year] [name of copyright owner]"
3.29 - *
3.30 - * Contributor(s):
3.31 - *
3.32 - * The Original Software is NetBeans. The Initial Developer of the Original
3.33 - * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
3.34 - *
3.35 - * If you wish your version of this file to be governed by only the CDDL
3.36 - * or only the GPL Version 2, indicate your decision by adding
3.37 - * "[Contributor] elects to include this software in this distribution
3.38 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
3.39 - * single choice of license, a recipient has the option to distribute
3.40 - * your version of this file under either the CDDL, the GPL Version 2 or
3.41 - * to extend the choice of license to its licensees as provided above.
3.42 - * However, if you add GPL Version 2 code and therefore, elected the GPL
3.43 - * Version 2 license, then the option applies only if the new code is
3.44 - * made subject to such option by the copyright holder.
3.45 - */
3.46 -package org.apidesign.html.json.spi;
3.47 -
3.48 -import java.lang.ref.WeakReference;
3.49 -import java.util.ArrayList;
3.50 -import java.util.Iterator;
3.51 -import java.util.LinkedList;
3.52 -import java.util.List;
3.53 -
3.54 -/**
3.55 - *
3.56 - * @author Jaroslav Tulach
3.57 - */
3.58 -final class Watcher {
3.59 - private static final LinkedList<Watcher> GLOBAL = new LinkedList<Watcher>();
3.60 -
3.61 - private final Proto proto;
3.62 - private final String prop;
3.63 -
3.64 - private Watcher(Proto proto, String prop) {
3.65 - this.proto = proto;
3.66 - this.prop = prop;
3.67 - }
3.68 -
3.69 - static void beginComputing(Proto p, String name) {
3.70 - synchronized (GLOBAL) {
3.71 - verifyUnlocked(p);
3.72 - final Watcher nw = new Watcher(p, name);
3.73 - GLOBAL.push(nw);
3.74 - }
3.75 - }
3.76 -
3.77 - static void verifyUnlocked(Proto p) {
3.78 - synchronized (GLOBAL) {
3.79 - for (Watcher w : GLOBAL) {
3.80 - if (w.proto == p) {
3.81 - throw new IllegalStateException("Re-entrant attempt to access " + p);
3.82 - }
3.83 - }
3.84 - }
3.85 - }
3.86 -
3.87 - static Observers accessingValue(Proto p, Observers observers, String propName) {
3.88 - synchronized (GLOBAL) {
3.89 - verifyUnlocked(p);
3.90 - for (Watcher w : GLOBAL) {
3.91 - if (observers == null) {
3.92 - observers = new Observers();
3.93 - }
3.94 - observers.add(w, new Ref(w, propName));
3.95 - }
3.96 - return observers;
3.97 - }
3.98 - }
3.99 -
3.100 - static Watchers finishComputing(Proto p, Watchers mine) {
3.101 - synchronized (GLOBAL) {
3.102 - Watcher w = GLOBAL.pop();
3.103 - if (w.proto != p) {
3.104 - throw new IllegalStateException("Inconsistency: " + w.proto + " != " + p);
3.105 - }
3.106 - if (mine == null) {
3.107 - mine = new Watchers();
3.108 - }
3.109 - mine.add(w);
3.110 - return mine;
3.111 - }
3.112 - }
3.113 -
3.114 - static Watcher computing(Proto proto, String prop) {
3.115 - proto.getClass();
3.116 - prop.getClass();
3.117 - return new Watcher(proto, prop);
3.118 - }
3.119 -
3.120 - @Override
3.121 - public String toString() {
3.122 - return "Watcher: " + proto + ", " + prop;
3.123 - }
3.124 -
3.125 - private static final class Ref extends WeakReference<Watcher> {
3.126 - private final String prop;
3.127 -
3.128 - public Ref(Watcher ref, String prop) {
3.129 - super(ref);
3.130 - this.prop = prop;
3.131 - }
3.132 -
3.133 - final Watcher watcher() {
3.134 - Watcher w = get();
3.135 - if (w != null && w.proto.watcher(w.prop) == w) {
3.136 - return w;
3.137 - }
3.138 - return null;
3.139 - }
3.140 - }
3.141 -
3.142 - static final class Watchers {
3.143 - private final List<Watcher> watchers = new ArrayList<Watcher>();
3.144 -
3.145 - Watcher find(String prop) {
3.146 - if (prop == null) {
3.147 - return null;
3.148 - }
3.149 - for (Watcher w : watchers) {
3.150 - if (prop.equals(w.prop)) {
3.151 - return w;
3.152 - }
3.153 - }
3.154 - return null;
3.155 - }
3.156 -
3.157 - final void add(Watcher w) {
3.158 - for (int i = 0; i < watchers.size(); i++) {
3.159 - Watcher ith = watchers.get(i);
3.160 - if (w.prop == null) {
3.161 - if (ith.prop == null) {
3.162 - watchers.set(i, w);
3.163 - return;
3.164 - }
3.165 - } else if (w.prop.equals(ith.prop)) {
3.166 - watchers.set(i, w);
3.167 - return;
3.168 - }
3.169 - }
3.170 - watchers.add(w);
3.171 - }
3.172 - }
3.173 -
3.174 - static final class Observers {
3.175 - private final List<Ref> observers = new ArrayList<Ref>();
3.176 -
3.177 - void valueHasMutated(String propName) {
3.178 - List<Watcher> mutated = new LinkedList<Watcher>();
3.179 - synchronized (GLOBAL) {
3.180 - Iterator<Ref> it = observers.iterator();
3.181 - while (it.hasNext()) {
3.182 - Ref ref = it.next();
3.183 - if (ref.get() == null) {
3.184 - it.remove();
3.185 - continue;
3.186 - }
3.187 - if (ref.prop.equals(propName)) {
3.188 - Watcher w = ref.watcher();
3.189 - if (w != null) {
3.190 - mutated.add(w);
3.191 - }
3.192 - }
3.193 - }
3.194 - }
3.195 - for (Watcher w : mutated) {
3.196 - w.proto.valueHasMutated(w.prop);
3.197 - }
3.198 - }
3.199 -
3.200 - void add(Watcher w, Ref r) {
3.201 - Thread.holdsLock(GLOBAL);
3.202 - if (w == null) {
3.203 - return;
3.204 - }
3.205 - Iterator<Ref> it = observers.iterator();
3.206 - while (it.hasNext()) {
3.207 - Ref ref = it.next();
3.208 - if (r == ref) {
3.209 - return;
3.210 - }
3.211 - final Watcher rw = ref.get();
3.212 - if (rw == null) {
3.213 - it.remove();
3.214 - continue;
3.215 - }
3.216 - if (rw == w && r.prop.equals(r.prop)) {
3.217 - return;
3.218 - }
3.219 - }
3.220 - observers.add(r);
3.221 - }
3.222 - }
3.223 -}