Skip to content

Instantly share code, notes, and snippets.

@tonypiazza
Last active August 29, 2015 14:25
Show Gist options
  • Save tonypiazza/e2811eae4dc654890d59 to your computer and use it in GitHub Desktop.
Save tonypiazza/e2811eae4dc654890d59 to your computer and use it in GitHub Desktop.
Implementation of CAS using AspectJ

Follow these steps to use the CAS annotation feature.

  1. Add the @EnableCAS annotation to inject CAS behavior into a class.

  2. Add the following to the VM arguments of your application:

    -javaagent:/home/user/.m2/repository/org/aspectj/aspectjweaver/1.8.6/aspectjweaver-1.8.6.jar

/*
* Copyright 2015 Piazza Software Consulting, LLC
*
* 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 com.piazzaconsulting.couchbase.cas;
/**
* Simple interface to describe behavior needed to support CAS.
*
* @author Tony Piazza
*/
public interface CheckAndSet {
long getCas();
void setCas(long cas);
}
/*
* Copyright 2015 Piazza Software Consulting, LLC
*
* 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 com.piazzaconsulting.couchbase.cas;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
/**
* Aspect for injecting CAS behavior into classes that will be stored in
* Couchbase.
*
* @author Tony Piazza
*/
@Aspect
public class CheckAndSetAspect {
public static class CheckAndSetSupportImpl implements CheckAndSet {
private long cas;
@Override
public long getCas() {
return cas;
}
@Override
public void setCas(long cas) {
this.cas = cas;
}
}
@DeclareParents(value="@EnableCAS *",defaultImpl=CheckAndSetSupportImpl.class)
private CheckAndSet implementedInterface;
}
/*
* Copyright 2015 Piazza Software Consulting, LLC
*
* 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 com.piazzaconsulting.couchbase.cas;
/**
* Utility class for using the CAS capability injected by the EnableCAS
* annotation.
*
* @author Tony Piazza
*/
public final class CheckAndSetUtil {
private CheckAndSetUtil() {
// prevents instantiation
}
/**
* Set the CAS value of the target object.
*
* @param target Object reference of target
* @param cas long CAS value
*/
public static void set(Object target, long cas) {
getObject(target).setCas(cas);
}
/**
* Get the CAS value of the target object.
*
* @param target Object reference of target
* @return long CAS value
*/
public static long get(Object obj) {
return getObject(obj).getCas();
}
private static CheckAndSet getObject(Object obj) {
if(!(obj instanceof CheckAndSet)) {
throw new IllegalArgumentException("Type does not implement " +
CheckAndSet.class.getName());
}
return (CheckAndSet)obj;
}
}
/*
* Copyright 2015 Piazza Software Consulting, LLC
*
* 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 com.piazzaconsulting.couchbase.cas;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation to identify classes that want CAS behavior injected.
*
* @author Tony Piazza
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface EnableCAS {
// nothing needed here
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment