I am trying to implement SpEL in my custom Annotation in a similar fashion how #Cachable implement
#Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
Here is my code Sample:
Custom Annotation:
#Target({ ElementType.METHOD })
#Retention(RetentionPolicy.RUNTIME)
public #interface StoreRequest {
public boolean enable() default true;
public String name() default "" ;
}
Aspect:
#Before("#annotation(storeRequest)")
public void saveRequest(JoinPoint ijoinPoint, StoreRequest storeRequest) {
if (storeRequest.enable()) {
System.out.println("Aspect in enabled for "+ storeRequest.name());
} else {
System.out.println("Aspect in disabled for "+ storeRequest.name();
}
}
Service:
#Override
#StoreRequest(name = "#name")
public void aspectCheck(String name){
....
...
...
}
Let's say the param value is BOB for aspectCheck method, This piece of code prints as "Aspect in enabled for #name". where as I expect is as "Aspect in enabled for BOB".
Now, I know that Spel doesn't work magically, and I need to write extra lines of code for my custom annotation to implement SpEL. I would appreciate if any one could help me how to do it.
Related
data item boolean flag won't hold its state when item is returned from server through dispatcher to Presenter (client side).
shared package
public class ResourceItem extends BaseResourceItem implements IsSerializable {
private String name;
public ResourceItem() {
super();
}
public ResourceItem(String name) {
super(true);
this.name = name;
}
}
public class BaseResourceItem {
private boolean removeEnabled = true;
public BaseResourceItem() {
super();
}
public BaseResourceItem(boolean removeEnabled) {
super();
this.removeEnabled = removeEnabled;
}
public boolean isRemoveEnabled() {
return removeEnabled;
}
public void setRemoveEnabled(boolean removeEnabled) {
this.removeEnabled = removeEnabled;
}
}
Flag in question is removeEnabled . By default it's true, and even though I set it to false in server side, when Presenter gets it, it's been set to false for some reason. Am I missing something with serialization? (can't think of anything else at this point).
Server package
#GenDispatch
public class GetModelSettings {
#Out(1)
List<ResourceItem> listOfSettings;
}
public class GetModelSettingsHandler implements ActionHandler<GetModelSettingsAction, GetModelSettingsResult> {
#Override
public GetModelSettingsResult execute(GetModelSettingsAction action, ExecutionContext context)
throws ActionException {
ResourceItem item1 = new ResourceItem();
ResourceItem item2 = new ResourceItem();
item2.setRemoveEnabled(false);
list.add(item1);
list.add(item2);
// item1 -> true
// item2 -> false
return new GetModelSettingsResult(list);
}
}
As you can see, a simple handler return a list. At this point, data is correct, one item has flag set to true, the other one to false.
Client package
public class ModelSettingsPresenter {
dispatcher.execute(new GetModelSettingsAction(), new AsyncCallback<GetModelSettingsResult>() {
#Override
public void onSuccess(GetModelSettingsResult result) {
itemList = result.getListOfSettings();
// itemList.get(0) -> true
// itemList.get(1) -> true
}
});
}
Data items both have flags set to true in this presenter. Any ideas why is this happening?
This has to do with serialization used with inheritance.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.
More on it can be found in different thread Java object Serialization and inheritance
I am trying to use the getSlingScriptHelper().getService in my project but it keeps returning null. I have done this in other projects and the implementation is similar. We are using sightly on AEM 6.3 in the project. My code below:
FOOModel :
public class FOOModel extends WCMUsePojo {
private static final Logger LOGGER = LoggerFactory.getLogger(FOOModel.class);
private String foo;
#Override
public void activate() throws Exception{
FOOInterface fooInterface = getSlingScriptHelper().getService(FOOInterface.class);
LOGGER.info("FOOInterface value is : " + fooInterface);
}
public String getFoo() {
return foo;
}
}
FooInterface :
public interface FOOInterface {
public String getFoo();
}
FOO Implementation :
#Component(metatype = true, immediate = true, label = "FOO Configuration", description = "OSGi Configuration FOO")
#Service(FOOInterface.class)
public class FOOImpl implements FOOInterface {
#Property(label = "FOO", description = "FOO to be provided")
public static final String FOO_URL = "foo.url";
private String foo;
#Activate
public void activate(ComponentContext componentContext){
Dictionary<?, ?> props = componentContext.getProperties();
this.foo = PropertiesUtil.toString(props.get(FOO_URL), StringUtils.EMPTY);
}
#Override
public String getSsoUrl() {
return foo;
}
}
The logs show "FOOInterface value is : null".
I've tried the sling model with class injection method but it did not work either.
EDIT : I have found that the service is not active. Attaching screenshot for the bundle status.
Most probably your FOOInterface service is not active. You can check /system/console/components to see its status.
The bundle that includes that service might not be properly installed. You can check its status at /system/console/bundles.
I have a problem.
I have in my new table two new fields
1) Name -> AccountNum, EDT--> DimensionDynamicAccount
2) Name -> AccountType, EDT--> LedgerJournalACType
class declaration
:
public class FormRun extends ObjectRun
{
DimensionDynamicAccountController dimAccountController;
}
init (for the form):
public void init()
{
super();
dimAccountController = DimensionDynamicAccountController::construct(
MyTable_ds,
fieldstr(MyTable, LedgerDimension),
fieldstr(MyTable, AccountType));
}
4. Override the following methods on the Segmented Entry control instance in the form design.
public void jumpRef()
{
dimAccountController.jumpRef();
}
public void loadAutoCompleteData(LoadAutoCompleteDataEventArgs _e)
{
super(_e);
dimAccountController.loadAutoCompleteData(_e);
}
public void segmentValueChanged(SegmentValueChangedEventArgs _e)
{
super(_e);
dimAccountController.segmentValueChanged(_e);
}
public void loadSegments()
{
super();
dimAccountController.parmControl(this);
dimAccountController.loadSegments();
}
public boolean validate()
{
boolean isValid;
isValid = super();
isValid = dimAccountController.validate() && isValid;
return isValid;
}
5. Override the following methods on the data source field that backs the Segmented Entry control.
public Common resolveReference(FormReferenceControl _formReferenceControl)
{
return dimAccountController.resolveReference();
}
Now my problem is Lookup only works for AccountType=="Ledger" not for customer, Vendor etc...
If I have a AccountType == Vendor or similant but different to Ledger I see this
I would want to have same the same thing that's in the LedgerJournalTrans Form
There is a solution,
thanks all,
enjoy
This might be too obvious, but I think you're missing the lookup() method.
See:
\Forms\LedgerJournalTransDaily\Designs\Design\[Tab:Tab]\[TabPage:OverViewTab]\[Grid:overviewGrid]\SegmentedEntry:LedgerJournalTrans_AccountNum\Methods\lookup
public void lookup()
{
if (!ledgerJournalEngine.accountNumLookup(ledgerJournalTrans_AccountNum,
ledgerJournalTrans,
ledgerJournalTrans.OffsetAccountType,
ledgerJournalTrans.parmOffsetAccount(),
ledgerJournalTrans_Asset))
{
super();
}
}
In my application, I have a service that requires a constructor parameter not resolved by Autofac, that I instantiate using a delegate factory:
public class Service
{
public Service(string parameter /*, ... other dependencies */)
{
}
public delegate Service Factory(string parameter);
}
This works great! I really love this feature.
I also like the Controlled Lifetime relationship, so I can let my component depend on a Func<Owned<ISomething>> like this:
public class Component
{
private Func<Owned<ISomething>> _somethingFactory;
/* constructor omitted for brevity */
public void DoSomethingUseful()
{
using (var ownedSomething = _somethingFactory())
{
/* Lots of useful code here */
}
}
}
My problem is that now I want to combine the two. I can't have an instance of Func<Owned<Service>> injected, because it needs that parameter, so my current solution is to abstract the factory away into another service, say IServiceFactory:
public interface IServiceFactory
{
Service Create(string parameter);
}
...implemented as such:
public class ServiceFactory : IServiceFactory
{
private Service.Factory _internalFactory;
public ServiceFactory(Service.Factory internalFactory)
{
_internalFactory = internalFactory;
}
public Service Create(string parameter)
{
return _internalFactory(parameter);
}
}
My component then becomes this:
public class Component
{
Func<Owned<IServiceFactory>> _serviceFactoryFactory;
/* ... */
}
The need for such a field name leaves a bad taste in my mouth to the point that I suspect there must be a cleaner way to handle this case.
Is there another way?
You could change your injected factory to include the string parameter:
private Func<string, Owned<ISomething>> _somethingFactory;
Then you can pass the string to the factory when you want to create a new instance:
public void DoSomethingUseful()
{
using (var ownedSomething = _somethingFactory("my parameter"))
{
/* Lots of useful code here */
}
}
I've created a .NET Fiddle with a small working sample.
I am trying to write a pointcut and advice which could print a string from following method -
public CustomerDto getCustomer(Integer customerCode){
CustomerDto customerDto = new CustomerDto();
String emailID =getEmailAddress();
customerDto.setEmailAddress(emailID);
customerDto.setEmployer(getEmployer());
customerDto.setSpouseName(getSpouse());
return customerDto;
}
I am unable to figure out a way by which a pointcut look at String emailID and then print the value of the same in an advice.
Maybe you need something like the following:
public privileged aspect LocalMethodCallAspect {
private pointcut localMethodExecution() : withincode(public CustomerDto TargetClass.getCustomer(Integer)) &&
call(private String TargetClass.getEmailAddress());
after() returning(String email) : localMethodExecution()
{
System.out.println(email);
}
}
Where TargetClass is a class containing getCustomer() and getEmailAddress() methods.
Or the same using #AspectJ:
#Aspect
public class LocalMethodCallAnnotationDrivenAspect {
#Pointcut("withincode(public CustomerDto TargetClass.getCustomer(Integer)) && " +
"call(private String TargetClass.getEmailAddress())")
private void localMethodExecution() {
}
#AfterReturning(pointcut="localMethodExecution()",returning="email")
public void printingEmail(String email) {
System.out.println(email);
}
}