diff --git a/src/org/redkale/boot/Application.java b/src/org/redkale/boot/Application.java index 4f820100f..79f49db3b 100644 --- a/src/org/redkale/boot/Application.java +++ b/src/org/redkale/boot/Application.java @@ -415,7 +415,7 @@ public final class Application { return false; } - }, Application.class, WatchFactory.class, NodeSncpServer.class, NodeHttpServer.class, NodeWatchServer.class); + }, Application.class, NodeSncpServer.class, NodeHttpServer.class, NodeWatchServer.class); //-------------------------------------------------------------------------- initResources(); } diff --git a/src/org/redkale/net/PrepareServlet.java b/src/org/redkale/net/PrepareServlet.java index 0a53ea50a..db9516aa9 100644 --- a/src/org/redkale/net/PrepareServlet.java +++ b/src/org/redkale/net/PrepareServlet.java @@ -55,6 +55,14 @@ public abstract class PrepareServlet newservlets = new HashSet<>(servlets); + newservlets.remove(servlet); + this.servlets = newservlets; + } + } + protected void putMapping(K key, S servlet) { synchronized (lock2) { Map newmappings = new HashMap<>(mappings); @@ -63,6 +71,28 @@ public abstract class PrepareServlet newmappings = new HashMap<>(mappings); + newmappings.remove(key); + this.mappings = newmappings; + } + } + + protected void removeMapping(S servlet) { + synchronized (lock2) { + List keys = new ArrayList<>(); + Map newmappings = new HashMap<>(mappings); + for (Map.Entry en : newmappings.entrySet()) { + if (en.getValue().equals(servlet)) { + keys.add(en.getKey()); + } + } + for (K key : keys) newmappings.remove(key); + this.mappings = newmappings; + } + } + protected S mappingServlet(K key) { return mappings.get(key); } diff --git a/src/org/redkale/net/http/HttpPrepareServlet.java b/src/org/redkale/net/http/HttpPrepareServlet.java index 57820b560..ed0ad88dc 100644 --- a/src/org/redkale/net/http/HttpPrepareServlet.java +++ b/src/org/redkale/net/http/HttpPrepareServlet.java @@ -8,7 +8,6 @@ package org.redkale.net.http; import org.redkale.util.AnyValue.DefaultAnyValue; import java.io.*; import java.util.*; -import java.util.AbstractMap.SimpleEntry; import java.util.function.*; import java.util.logging.*; import java.util.regex.*; @@ -28,12 +27,12 @@ public class HttpPrepareServlet extends PrepareServlet, HttpServlet>[] regArray = null; //regArray 包含 regWsArray + protected MappingEntry[] regArray = null; //regArray 包含 regWsArray + + protected MappingEntry[] regWsArray = null; protected Map wsmappings = new HashMap<>(); //super.mappings 包含 wsmappings - protected SimpleEntry, WebSocketServlet>[] regWsArray = null; - protected HttpServlet resourceHttpServlet = new HttpResourceServlet(); protected final Map allMapStrings = new HashMap<>(); @@ -44,6 +43,30 @@ public class HttpPrepareServlet extends PrepareServlet[] forbidURIPredicates; //禁用的URL的Predicate, 必须与 forbidURIMaps 保持一致 + public HttpServlet removeHttpServlet(HttpServlet servlet) { + HttpServlet rs = null; + synchronized (allMapStrings) { + //待开发 + } + return rs; + } + + public HttpServlet removeHttpServlet(Class servletType) { + HttpServlet rs = null; + synchronized (allMapStrings) { + //待开发 + } + return rs; + } + + public HttpServlet removeHttpServlet(String mapping) { + HttpServlet rs = null; + synchronized (allMapStrings) { + //待开发 + } + return rs; + } + public boolean addForbidURIReg(final String urlreg) { if (urlreg == null || urlreg.isEmpty()) return false; synchronized (excludeLock) { @@ -140,9 +163,9 @@ public class HttpPrepareServlet extends PrepareServlet, WebSocketServlet> en : regWsArray) { - if (en.getKey().test(uri)) { - servlet = en.getValue(); + for (MappingEntry en : regWsArray) { + if (en.predicate.test(uri)) { + servlet = en.servlet; break; } } @@ -154,9 +177,9 @@ public class HttpPrepareServlet extends PrepareServlet, HttpServlet> en : regArray) { - if (en.getKey().test(uri)) { - servlet = en.getValue(); + for (MappingEntry en : regArray) { + if (en.predicate.test(uri)) { + servlet = en.servlet; break; } } @@ -216,19 +239,19 @@ public class HttpPrepareServlet extends PrepareServlet(Pattern.compile(mapping).asPredicate(), servlet); + regArray = new MappingEntry[1]; + regArray[0] = new MappingEntry(mapping, Pattern.compile(mapping).asPredicate(), servlet); } else { regArray = Arrays.copyOf(regArray, regArray.length + 1); - regArray[regArray.length - 1] = new SimpleEntry<>(Pattern.compile(mapping).asPredicate(), servlet); + regArray[regArray.length - 1] = new MappingEntry(mapping, Pattern.compile(mapping).asPredicate(), servlet); } if (servlet instanceof WebSocketServlet) { if (regWsArray == null) { - regWsArray = new SimpleEntry[1]; - regWsArray[0] = new SimpleEntry<>(Pattern.compile(mapping).asPredicate(), (WebSocketServlet) servlet); + regWsArray = new MappingEntry[1]; + regWsArray[0] = new MappingEntry(mapping, Pattern.compile(mapping).asPredicate(), (WebSocketServlet) servlet); } else { regWsArray = Arrays.copyOf(regWsArray, regWsArray.length + 1); - regWsArray[regWsArray.length - 1] = new SimpleEntry<>(Pattern.compile(mapping).asPredicate(), (WebSocketServlet) servlet); + regWsArray[regWsArray.length - 1] = new MappingEntry(mapping, Pattern.compile(mapping).asPredicate(), (WebSocketServlet) servlet); } } } else if (mapping != null && !mapping.isEmpty()) { @@ -285,4 +308,19 @@ public class HttpPrepareServlet extends PrepareServlet predicate; + + public final HttpServlet servlet; + + public MappingEntry(String mapping, Predicate predicate, HttpServlet servlet) { + this.mapping = mapping; + this.predicate = predicate; + this.servlet = servlet; + } + + } } diff --git a/src/org/redkale/net/http/HttpServer.java b/src/org/redkale/net/http/HttpServer.java index a66689f14..e62eb459c 100644 --- a/src/org/redkale/net/http/HttpServer.java +++ b/src/org/redkale/net/http/HttpServer.java @@ -57,6 +57,40 @@ public class HttpServer extends Server 泛型 + * @param servletType Class + * + * @return HttpServlet + */ + public HttpServlet removeHttpServlet(Class servletType) { + return ((HttpPrepareServlet) this.prepare).removeHttpServlet(servletType); + } + + /** + * 删除HttpServlet + * + * @param mapping String + * + * @return HttpServlet + */ + public HttpServlet removeHttpServlet(String mapping) { + return ((HttpPrepareServlet) this.prepare).removeHttpServlet(mapping); + } + /** * 屏蔽请求URL的正则表达式 * diff --git a/src/org/redkale/net/sncp/SncpDynServlet.java b/src/org/redkale/net/sncp/SncpDynServlet.java index 924beef8a..6390cafe3 100644 --- a/src/org/redkale/net/sncp/SncpDynServlet.java +++ b/src/org/redkale/net/sncp/SncpDynServlet.java @@ -42,10 +42,6 @@ public final class SncpDynServlet extends SncpServlet { private final boolean finest = logger.isLoggable(Level.FINEST); - private final Class type; - - private final String serviceName; - private final DLong serviceid; private final HashMap actions = new HashMap<>(); @@ -53,8 +49,7 @@ public final class SncpDynServlet extends SncpServlet { private Supplier bufferSupplier; public SncpDynServlet(final BsonConvert convert, final String serviceName, final Class type, final Service service) { - this.serviceName = serviceName; - this.type = type; + super(serviceName, type, service); this.serviceid = Sncp.hash(type.getName() + ':' + serviceName); Set actionids = new HashSet<>(); for (java.lang.reflect.Method method : service.getClass().getMethods()) { diff --git a/src/org/redkale/net/sncp/SncpPrepareServlet.java b/src/org/redkale/net/sncp/SncpPrepareServlet.java index e7f2130b8..8cf0aff5a 100644 --- a/src/org/redkale/net/sncp/SncpPrepareServlet.java +++ b/src/org/redkale/net/sncp/SncpPrepareServlet.java @@ -25,15 +25,30 @@ public class SncpPrepareServlet extends PrepareServlet SncpServlet removeSncpServlet(String name, Class type) { + SncpServlet rs = null; + for (SncpServlet servlet : getServlets()) { + if (servlet.serviceName.equals(name) && servlet.type.equals(type)) { + rs = servlet; + break; + } + } + if (rs != null) { + removeMapping(rs); + removeServlet(rs); + } + return rs; + } + public List getSncpServlets() { return new ArrayList<>(getServlets()); } diff --git a/src/org/redkale/net/sncp/SncpServer.java b/src/org/redkale/net/sncp/SncpServer.java index fa500da93..acfd75bdb 100644 --- a/src/org/redkale/net/sncp/SncpServer.java +++ b/src/org/redkale/net/sncp/SncpServer.java @@ -73,6 +73,35 @@ public class SncpServer extends Server 泛型 + * @param resname String + * @param type Class + * + * @return SncpServlet + */ + public SncpServlet removeSncpServlet(String resname, Class type) { + return ((SncpPrepareServlet) this.prepare).removeSncpServlet(resname, type); + } + + /** + * 删除SncpServlet + * + * @param sncpService Service + * + * @return SncpServlet + */ + public SncpServlet removeSncpServlet(Service sncpService) { + SncpServlet servlet = null; + String resname = Sncp.getResourceName(sncpService); + for (Class type : Sncp.getResourceTypes(sncpService)) { + servlet = ((SncpPrepareServlet) this.prepare).removeSncpServlet(resname, type); + } + return servlet; + } + public void addSncpServlet(Service sncpService) { for (Class type : Sncp.getResourceTypes(sncpService)) { SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), Sncp.getResourceName(sncpService), type, sncpService); diff --git a/src/org/redkale/net/sncp/SncpServlet.java b/src/org/redkale/net/sncp/SncpServlet.java index 89ce86cd6..28337fbef 100644 --- a/src/org/redkale/net/sncp/SncpServlet.java +++ b/src/org/redkale/net/sncp/SncpServlet.java @@ -8,6 +8,7 @@ package org.redkale.net.sncp; import java.util.Objects; import java.util.concurrent.*; import org.redkale.net.*; +import org.redkale.service.Service; import org.redkale.util.*; /** @@ -19,6 +20,26 @@ import org.redkale.util.*; */ public abstract class SncpServlet extends Servlet implements Comparable { + protected final Class type; + + protected final String serviceName; + + protected final Service service; + + protected SncpServlet(String serviceName, Class type, Service service) { + this.type = type; + this.service = service; + this.serviceName = serviceName; + } + + public Service getService() { + return service; + } + + public String getServiceName() { + return serviceName; + } + public abstract DLong getServiceid(); protected ExecutorService getExecutor() { diff --git a/src/org/redkale/util/Utility.java b/src/org/redkale/util/Utility.java index d508d9625..711d818ee 100644 --- a/src/org/redkale/util/Utility.java +++ b/src/org/redkale/util/Utility.java @@ -11,6 +11,7 @@ import java.nio.ByteBuffer; import java.nio.charset.*; import java.time.*; import java.util.*; +import java.util.function.Predicate; import java.util.zip.GZIPInputStream; import javax.net.ssl.*; @@ -276,6 +277,30 @@ public final class Utility { return news; } + /** + * 将符合条件的元素从数组中删除 + * + * @param 泛型 + * @param array 原数组 + * @param filter Predicate + * + * @return 新数组 + */ + public static T[] remove(final T[] array, final Predicate filter) { + if (array == null || array.length == 0 || filter == null) return array; + final T[] news = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length); + int index = 0; + for (int i = 0; i < news.length; i++) { + if (!filter.test(array[i])) { + news[index++] = array[i]; + } + } + if (index == news.length) return news; + final T[] rs = (T[]) Array.newInstance(array.getClass().getComponentType(), index); + System.arraycopy(news, 0, rs, 0, index); + return rs; + } + /** * 判断字符串是否包含指定的字符,包含返回true * diff --git a/src/org/redkale/watch/WatchFactory.java b/src/org/redkale/watch/WatchFactory.java deleted file mode 100644 index b5d5ad66c..000000000 --- a/src/org/redkale/watch/WatchFactory.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.watch; - -import java.lang.ref.WeakReference; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.LongSupplier; - -/** - * - *

- * 详情见: https://redkale.org - * - * @author zhangjx - */ -public final class WatchFactory { - - private static final WatchFactory instance = new WatchFactory("", null); - - private final List> chidren = new CopyOnWriteArrayList<>(); - - private final List> beans = new CopyOnWriteArrayList<>(); - - private final String name; - - private final WatchFactory parent; - - private WatchFactory(String name, WatchFactory parent) { - this.name = name; - this.parent = parent; - } - - public void register(WatchNode bean) { - if (bean == null) return; - checkName(bean.getName()); - beans.add(new WeakReference<>(bean)); - } - - public static WatchFactory root() { - return instance; - } - - public WatchFactory createChild(final String name) { - WatchFactory child = new WatchFactory(name, this); - this.chidren.add(new WeakReference<>(child)); - return child; - } - - public List getChildren() { - List result = new ArrayList<>(); - for (WeakReference ref : chidren) { - WatchFactory rf = ref.get(); - if (rf != null) result.add(rf); - } - return result; - } - - public List getWatchNodes() { - List result = new ArrayList<>(); - for (WeakReference ref : beans) { - WatchNode rf = ref.get(); - if (rf != null) result.add(rf); - } - return result; - } - - public WatchNumber createWatchNumber(String name) { - return createWatchNumber(name, "", false, 0); - } - - public WatchNumber createWatchNumber(String name, boolean interval) { - return createWatchNumber(name, "", interval, 0); - } - - public WatchNumber createWatchNumber(String name, String description) { - return createWatchNumber(name, description, false, 0); - } - - public WatchNumber createWatchNumber(String name, String description, long v) { - return createWatchNumber(name, description, false, 0); - } - - public WatchNumber createWatchNumber(String name, String description, boolean interval) { - return createWatchNumber(name, description, interval, 0); - } - - public WatchNumber createWatchNumber(String name, String description, boolean interval, long v) { - return new WatchNumber(name, description, interval, v); - } - - public void register(String name, LongSupplier supplier) { - register(name, "", supplier); - } - - public void register(String name, String description, LongSupplier supplier) { - register(new WatchSupplier(name, description, supplier)); - } - - public void checkName(String name) { - if (name == null || (!name.isEmpty() && !name.matches("^[a-zA-Z0-9_;/\\-\\.\\[\\]\\(\\)]+$")) || name.contains("//")) { - throw new IllegalArgumentException("Watch.name(" + name + ") contains illegal character, must be (a-z,A-Z,0-9,/,_,.,(,),-,[,]) and cannot contains //"); - } - } - - protected boolean inject(final Object src) { - return inject(src, null); - } - - protected boolean inject(final Object src, final T attachment) { - return inject(src, attachment, new ArrayList<>()); - } - - private boolean inject(final Object src, final T attachment, final List list) { - if (src == null) return false; - try { - list.add(src); - Class clazz = src.getClass(); - do { - for (Field field : clazz.getDeclaredFields()) { - if (Modifier.isFinal(field.getModifiers())) continue; - field.setAccessible(true); - final Class type = field.getType(); - Watchable wo = field.getAnnotation(Watchable.class); - if (wo == null && !WatchNode.class.isAssignableFrom(type)) continue; - } - } while ((clazz = clazz.getSuperclass()) != Object.class); - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/org/redkale/watch/WatchNode.java b/src/org/redkale/watch/WatchNode.java deleted file mode 100644 index 0759ee055..000000000 --- a/src/org/redkale/watch/WatchNode.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.watch; - -/** - * - *

详情见: https://redkale.org - * @author zhangjx - */ -interface WatchNode { - - public String getName(); - - public String getDescription(); - - public long getValue(); - - public boolean isInterval(); -} diff --git a/src/org/redkale/watch/WatchNumber.java b/src/org/redkale/watch/WatchNumber.java deleted file mode 100644 index e0e919d4c..000000000 --- a/src/org/redkale/watch/WatchNumber.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.watch; - -import java.beans.*; -import java.util.concurrent.atomic.*; - -/** - * - *

详情见: https://redkale.org - * @author zhangjx - */ -final class WatchNumber extends AtomicLong implements WatchNode { - - private final boolean interval; - - private final String name; - - private final String description; - - @ConstructorProperties({"name", "description", "interval", "value"}) - protected WatchNumber(String name, String description, boolean interval, long value) { - this.name = name; - this.description = description; - this.interval = interval; - this.set(value); - } - - @Override - public String getName() { - return name; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public long getValue() { - return super.longValue(); - } - - @Override - public boolean isInterval() { - return interval; - } - -} diff --git a/src/org/redkale/watch/WatchSupplier.java b/src/org/redkale/watch/WatchSupplier.java deleted file mode 100644 index efb9c778e..000000000 --- a/src/org/redkale/watch/WatchSupplier.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.watch; - -import java.util.function.LongSupplier; - -/** - * - *

详情见: https://redkale.org - * @author zhangjx - */ -public final class WatchSupplier implements WatchNode { - - private final String name; - - private final String description; - - private final LongSupplier supplier; - - WatchSupplier(String name, String description, LongSupplier supplier) { - this.name = name; - this.description = description; - this.supplier = supplier; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public String getDescription() { - return this.description; - } - - @Override - public long getValue() { - return supplier == null ? Long.MIN_VALUE : supplier.getAsLong(); - } - - @Override - public boolean isInterval() { - return false; - } -} diff --git a/src/org/redkale/watch/Watchable.java b/src/org/redkale/watch/Watchable.java deleted file mode 100644 index 0cf7ee171..000000000 --- a/src/org/redkale/watch/Watchable.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.watch; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 该注解只能放在field类型为Collection, Map, 或者java.util.concurrent.atomic.AtomicXXX的Number类); - * - *

- * 详情见: https://redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({FIELD, METHOD}) -@Retention(RUNTIME) -@interface Watchable { - - String name(); - - String description() default ""; - - /** - * 该值指明是不是只收集阶段数据, 而且被注解的字段只能被赋予java.util.concurrent.atomic.AtomicXXX的Number类型字段。 - * 例如收集每分钟的注册用户数, 就需要将interval设置true。 - * - * @return 是否收集 - */ - boolean interval() default false; -}