Skip to content

Commit

Permalink
Redisson's Spring custom namespace support
Browse files Browse the repository at this point in the history
  • Loading branch information
jackygurui committed Mar 8, 2017
1 parent 7421ff9 commit 6ae8f8f
Show file tree
Hide file tree
Showing 36 changed files with 5,287 additions and 23 deletions.
1 change: 1 addition & 0 deletions redisson/pom.xml
Expand Up @@ -428,6 +428,7 @@
<useDefaultExcludes>true</useDefaultExcludes>
<mapping>
<java>JAVADOC_STYLE</java>
<xsd>XML_STYLE</xsd>
</mapping>
<strictCheck>true</strictCheck>
<useDefaultMapping>true</useDefaultMapping>
Expand Down
6 changes: 6 additions & 0 deletions redisson/src/main/java/org/redisson/Redisson.java
Expand Up @@ -357,7 +357,13 @@ public RScheduledExecutorService getExecutorService(String name) {
}

@Override
@Deprecated
public RScheduledExecutorService getExecutorService(Codec codec, String name) {
return getExecutorService(name, codec);
}

@Override
public RScheduledExecutorService getExecutorService(String name, Codec codec) {
return new RedissonExecutorService(codec, connectionManager.getCommandExecutor(), this, name);
}

Expand Down
16 changes: 16 additions & 0 deletions redisson/src/main/java/org/redisson/api/RedissonClient.java
Expand Up @@ -742,12 +742,28 @@ public interface RedissonClient {
* Returns ScheduledExecutorService by name
* using provided codec for task, response and request serialization
*
* Please use getExecutorService(String name, Codec codec) method instead.
*
* @deprecated - use {@link #getExecutorService(String, Codec)} instead.
*
* @param name - name of object
* @param codec - codec for task, response and request
* @return ScheduledExecutorService object
*/
@Deprecated
RScheduledExecutorService getExecutorService(Codec codec, String name);

/**
* Returns ScheduledExecutorService by name
* using provided codec for task, response and request serialization
*
* @param name - name of object
* @param codec - codec for task, response and request
* @return ScheduledExecutorService object
* @since 2.8.2
*/
RScheduledExecutorService getExecutorService(String name, Codec codec);

/**
* Returns object for remote operations prefixed with the default name (redisson_remote_service)
*
Expand Down
@@ -0,0 +1,44 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.misc;

import java.lang.reflect.InvocationTargetException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.support.ArgumentConvertingMethodInvoker;

/**
*
* @author Rui Gu (https://github.com/jackygurui)
*/
public class BeanMethodInvoker extends ArgumentConvertingMethodInvoker
implements InitializingBean {

@Override
public void afterPropertiesSet() throws Exception {
prepare();
try {
invoke();
} catch (InvocationTargetException ex) {
if (ex.getTargetException() instanceof Exception) {
throw (Exception) ex.getTargetException();
}
if (ex.getTargetException() instanceof Error) {
throw (Error) ex.getTargetException();
}
throw ex;
}
}
}
@@ -0,0 +1,84 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.support;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.Assert;
import org.w3c.dom.Element;

/**
*
* @author Rui Gu (https://github.com/jackygurui)
*/
public abstract class AbstractRedissonNamespaceDefinitionParser
extends AbstractSingleBeanDefinitionParser {

protected final RedissonNamespaceParserSupport helper;
private final RedissonNamespaceDecorator decorator;
private final String parentRefAttribute;

protected AbstractRedissonNamespaceDefinitionParser(RedissonNamespaceParserSupport helper, String parentRefAttribute) {
this.helper = helper;
this.parentRefAttribute = parentRefAttribute;
this.decorator = new RedissonNamespaceDefaultDecorator();
}

public AbstractRedissonNamespaceDefinitionParser(RedissonNamespaceParserSupport helper, String parentRefAttribute, RedissonNamespaceDecorator decorator) {
this.helper = helper;
this.parentRefAttribute = parentRefAttribute;
this.decorator = decorator;
}

@Override
protected final void doParse(Element element, BeanDefinitionBuilder builder) {
}

@Override
protected final void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
Assert.state(helper.isRedissonNS(element),
"Illegal state. "
+ this.getClass().getName()
+ " can only parse "
+ RedissonNamespaceParserSupport.REDISSON_NAMESPACE
+ " namespace elements");
Assert.state(element.hasAttribute(parentRefAttribute),
"Illegal state. property \"" + parentRefAttribute
+ "\" is required in the \""
+ helper.getName(element)
+ "\" element.");

helper.populateIdAttribute(element, builder, parserContext);
AbstractBeanDefinition bd = builder.getRawBeanDefinition();
parseNested(element, parserContext, builder, bd);
decorator.decorate(element, parserContext, builder, helper);
parserContext.getDelegate().parseQualifierElements(element, bd);
if (parserContext.isNested()) {
helper.registerBeanDefinition(builder, element, parserContext);
}
}

protected abstract void parseNested(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, BeanDefinition bd);

@Override
protected final boolean shouldGenerateIdAsFallback() {
return true;
}

}
@@ -0,0 +1,44 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.support;

import org.redisson.api.RQueue;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.Assert;
import org.w3c.dom.Element;

/**
*
* @author Rui Gu (https://github.com/jackygurui)
*/
public class DelayedQueueDecorator implements RedissonNamespaceDecorator {

private static final String DESTINATION_QUEUE_REF = "destination-queue-ref";

@Override
public void decorate(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, RedissonNamespaceParserSupport helper) {
Assert.state(element.hasAttribute(DESTINATION_QUEUE_REF),
"Illegal state. property \"" + DESTINATION_QUEUE_REF
+ "\" is required in the \""
+ helper.getName(element)
+ "\" element.");
helper.addConstructorArgs(new RuntimeBeanReference(
helper.getAttribute(element, DESTINATION_QUEUE_REF)),
RQueue.class, builder);
}
}
@@ -0,0 +1,95 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.support;

import org.redisson.api.LocalCachedMapOptions;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.Conventions;
import org.springframework.util.Assert;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
*
* @author Rui Gu (https://github.com/jackygurui)
*/
public class LocalCachedMapOptionsDecorator implements RedissonNamespaceDecorator {

@Override
public void decorate(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, RedissonNamespaceParserSupport helper) {
NodeList list = element.getElementsByTagNameNS(
RedissonNamespaceParserSupport.REDISSON_NAMESPACE,
RedissonNamespaceParserSupport.LOCAL_CACHED_MAP_OPTIONS_ELEMENT);
Element options = null;
String id;
if (list.getLength() == 1) {
options = (Element) list.item(0);
id = invokeOptions(options, parserContext, helper);
for (int i = 0; i < options.getAttributes().getLength(); i++) {
Attr item = (Attr) options.getAttributes().item(i);
if (helper.isEligibleAttribute(item)
&& !RedissonNamespaceParserSupport.TIME_TO_LIVE_UNIT_ATTRIBUTE
.equals(item.getLocalName())
&& !RedissonNamespaceParserSupport.MAX_IDLE_UNIT_ATTRIBUTE
.equals(item.getLocalName())) {
helper.invoker(id,
helper.getName(item),
new Object[]{item.getValue()},
parserContext);
}
}
invokeTimeUnitOptions(options, id, parserContext, helper,
RedissonNamespaceParserSupport.TIME_TO_LIVE_ATTRIBUTE,
RedissonNamespaceParserSupport.TIME_TO_LIVE_UNIT_ATTRIBUTE);

invokeTimeUnitOptions(options, id, parserContext, helper,
RedissonNamespaceParserSupport.MAX_IDLE_ATTRIBUTE,
RedissonNamespaceParserSupport.MAX_IDLE_UNIT_ATTRIBUTE);
} else {
id = invokeOptions(options, parserContext, helper);
}
helper.addConstructorArgs(new RuntimeBeanReference(id),
LocalCachedMapOptions.class, builder);
}

private String invokeOptions(Element element, ParserContext parserContext, RedissonNamespaceParserSupport helper) {
BeanComponentDefinition defaultOption
= helper.factoryInvoker(element, LocalCachedMapOptions.class,
"defaults", null, parserContext);
return defaultOption.getName();
}

private void invokeTimeUnitOptions(Element element, String id, ParserContext parserContext, RedissonNamespaceParserSupport helper, String timeAttrubute, String timeUnitAttribute) {
if (helper.hasAttribute(element, timeUnitAttribute)) {
Assert.state(
helper.hasAttribute(element, timeAttrubute),
"Missing \"" + timeAttrubute + "\" attribute in \""
+ RedissonNamespaceParserSupport.LOCAL_CACHED_MAP_OPTIONS_ELEMENT
+ "\" element.");
helper.invoker(id,
Conventions.attributeNameToPropertyName(timeAttrubute),
new Object[]{
Integer.parseInt(
helper.getAttribute(element, timeAttrubute)),
helper.getAttribute(element, timeUnitAttribute)},
parserContext);
}
}
}
@@ -0,0 +1,48 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.support;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
*
* @author Rui Gu (https://github.com/jackygurui)
*/
public class ReadWriteLockDecorator implements RedissonNamespaceDecorator {


@Override
public void decorate(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, RedissonNamespaceParserSupport helper) {
parseNested(element, RedissonNamespaceParserSupport.READ_LOCK_ELEMENT, parserContext, builder, helper);
parseNested(element, RedissonNamespaceParserSupport.WRITE_LOCK_ELEMENT, parserContext, builder, helper);
}

private void parseNested(Element element, String eltType, ParserContext parserContext, BeanDefinitionBuilder builder, RedissonNamespaceParserSupport helper) {
NodeList list = element.getElementsByTagNameNS(
RedissonNamespaceParserSupport.REDISSON_NAMESPACE, eltType);
if (list.getLength() == 1) {
Element elt = (Element) list.item(0);
helper.setAttribute(elt, RedissonNamespaceParserSupport.READ_WRITE_LOCK_REF_ATTRIBUTE,
helper.getAttribute(element,
RedissonNamespaceParserSupport.ID_ATTRIBUTE));
parserContext.getDelegate()
.parseCustomElement(elt, builder.getRawBeanDefinition());
}
}
}

0 comments on commit 6ae8f8f

Please sign in to comment.