How to access an abstract protected function in Zend - zend-framework

what can I do to make the abstract function work in the emaillogger class?
class EmailLogger extends Zend_Log_Writer_Abstract
and I want to use the function _write
protected function _write($event)
{
$this->_events[] = $this->_formatter->format($event);
}
then I got this error
Class EmailLogger contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Zend_Log_FactoryInterface::factory)
I am not really sure what to do here
I try'd to use implements Zend_Log_FactoryInterface, but it diddn't work
thanks, Richard

Zend_Log_Writer_Abstract implements Zend_Log_FactoryInterface which has the following code:
static public function factory($config);
This forces the Zend_Log_Writer_Abstract and any child classes to also have a factory method. To satisfy this requirement, you could put in a wrapper method which calls the parent method:
class EmailLogger extends Zend_Log_Writer_Abstract
{
// Add this method in conjunction to what you already have in your class
public static function factory($config)
{
parent::factory($config);
}
}

Related

(OOP) Implementing a pre-programmed function in a class

An experimental/theoretical question concerning any OOP language (Java, C#, Typescript, etc..)
Usually, when implementing an interface in a class, one has to override all the functions of that interface in the class by having to write the code for each function from that interface. And every class that implements this interface has to have its own code for those functions. Suppose we have an interface called Test that has a function called foo() in which I want the following code System.out.println("This is an interface function");.Usually one has to make an interface and declare the function and then writes the code in every implementing class
But what if there is some "theoretical" way of having all of the function written in the interface and every implementing class can just call it without having to override. Something like the following (using Java as a base language):
interface Test {
public foo() {
System.out.println("Test log.")
}
}
class Class1 implements Test {
constructor() {}
}
class Class2 implements Test {
constructor() {}
}
class Main {
public static void main() {
Class1 f1 = new Class1();
Class2 f2 = new Class2();
f1.foo();
f2.foo();
}
}
Java has this feature since Java 8. Interfaces can have default implementations where the class is free to override them, but not required to do so.
interface Test {
default void foo() {
System.out.println("Test log.");
}
}

AEM 6.3 - Inheritance in Sling Use classes

In AEM, I have a Use class A which extends WCMUsePojo. It has one activate() method with #Override annotation where I read the property (lets say product) and assign to variable. Also, I have a getter method to read the property. Now, there is another class B which extends the Class A and has activate() method with #Override annotation. In activate method I am reading one more property.
Now, from HTL , I refer the Class B, and was trying to get "product property" (assuming that this property would be available in Class B via inheritance), But I am getting null value. But when I change the property modifier to static in Class A, then it works fine.
See the code below.
public class ClassA extends WCMUsePojo {  
private String product;
 
#Override  
public void activate() throws Exception {    
product = getProperties().get(“product”, "");
}
  
public String getProduct() {    
return product;  
}
}
public class ClassB extends ClassA {  
private String lotno;
 
#Override  
public void activate() throws Exception {    
lotno = getProperties().get(“lotno”, "");
}
  
public String getLotno() {    
return lotno;  
}
}
<div data-sly-use.productDetails="test.sample.ClassB"/>
${productDetails.product}
${productDetails.product} is null unless I change the product property to static in ClassA. Can somebody explain why is that so?
Just add super.activate() in your activate-method of class B.
This is Standard-Java behavior. An overridden method replaces the inherited method. The child-class has to call super.method-xyz() to re-use it. So the child class can control if the inherited method is called and when.
Additional remarks:
In case of an constructor you must call super(), because also the super-class must be initialized.
If you should use Sling-Models (what is mostly recommended), then you have the same effect. The annotation #PostConstruct is also only used for the child class. This is more confusing for everybody. That's why I don't recommend inheritance for Sling-Models in my projects. Often it is not needed.

Dagger2: wildcard with Generics

I'm new to Dagger2 and DI in general, but I'm interested to populate a map with injected keys/values. The problem is that it works if I provide the exact types, I can't make it work with wildcards, any solution for that?
#Module
public class SimpleIssueModule
{
#Provides
#Singleton
#IntoMap
#StringKey("simple_issue")
public SimpleIssue provideSimpleIssue()
{
return new SimpleIssue();
}
}
#Module
public class DaggerFactoryModule
{
#Provides
#Singleton
public Factory provideFactory(Map<String, Provider< ? extends Issue>> map)
{
return new Factory(map);
}
}
If you want a map of Provider< ? extends Issue>> map, then you need to use Issue as the type returned in your module. Dagger will not do any casting or guessing on its own.
#Provides
#Singleton
#IntoMap
#StringKey("simple_issue")
public Issue provideSimpleIssue() {
return new SimpleIssue();
}
what to do in case I need a Module that provides a base class (Issue) into a Map and also need a provider of the concrete class (SimpleIssue) and I would like it to be Singleton (same instance returns in both cases)
In this case you provide the #Singleton of SimpleIssue.
#Provides
#Singleton
public SimpleIssue provideSimpleIssue() {
return new SimpleIssue();
}
// or you can use constructor injection, dropping the method above...
#Singleton
public class SimpleIssue {
#Inject
public SimpleIssue(...) {
}
}
Then you bind this instance into a Map. There is no need for a scope, since the implementation should declare it (as done above).
#Provides
#IntoMap
#StringKey("simple_issue")
public Issue provideSimpleIssue(SimpleIssue issue) {
return issue;
}
// or alternatively with `#Binds` when using an abstract class / interface
// this leads to actually better performing dagger code
#Binds
#IntoMap
#StringKey("simple_issue")
public Issue provideSimpleIssue(SimpleIssue issue);

Inconsistent behaviour on a fake(interface vs abstract class) using fakeiteasy

I had following code
public interface IFoo
{
void Execute();
}
public abstract class FooBar: IFoo
{
public void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
and following test case to test the Execute() method
[Fact]
public void When_execute_method_called_Expect_executionTime_is_set()
{
var sutMethod = A.Fake<FooBar>();
A.CallTo(sutMethod).
Where(x => x.Method.Name == "OnExecute").
Invokes(x => Thread.Sleep(100)));
sutMethod.Execute();
Assert.NotEqual(0, sutMethod.Result.ExecutionTime.Ticks);
}
sutMethod.Execute(); call would go to FooBar.Execute()
later I decided to make the interface into an abstract class
public abstract class IFoo
{
public abstract void Execute();
}
public abstract class FooBar:IFoo
{
public override void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
Now sutMethod.Execute(); call does not invoke FooBar.Execute()
I thought FakeItEasy would handles interface and abstract classes as equal.What am I missing?
Update
# Blair Conrad provided the reasoning for the behaviour
Is it possible to make minimal changes to the test case to get the original behaviour back?
thanks
The difference is due to the overrideability of the method Execute on FooBar.
FakeItEasy can only override virtual members, abstract members, or interface members.
In your original example, when IFooBar is an interface and FooBar implements it, Execute is a concrete method. It's not virtual, nor is it abstract. Thus FakeItEasy can't intercept calls to it, and the original method is executed.
Once you change IFooBar to an abstract class, you have an abstract IFooBar.Execute, which you override in FooBar. As such, FooBar.Execute is now virtual and can be intercepted by FakeItEasy. Which it does, so your implementation is not called.
Following addition help solve the issue
A.CallTo(() => sutMethod.Execute()).CallsBaseMethod();
This calls the virtual method Executeof FooBar

Java8 overriding (extending) default method

Suppose we have a default method in a interface,
in implementing class if we need to add some additional logic besides the one the default method already does we have to copy the whole method? is there any possibility to reuse default method... like we do with abstract class
super.method()
// then our stuff...
You can invoke it like this:
interface Test {
public default void method() {
System.out.println("Default method called");
}
}
class TestImpl implements Test {
#Override
public void method() {
Test.super.method();
// Class specific logic here.
}
}
This way, you can easily decide which interface default method to invoke, by qualifying super with the interface name:
class TestImpl implements A, B {
#Override
public void method() {
A.super.method(); // Call interface A method
B.super.method(); // Call interface B method
}
}
This is the case why super.method() won't work. As it would be ambiguous call in case the class implements multiple interfaces.