Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.Plugin;
import com.sun.tools.xjc.model.CPluginCustomization;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.FieldOutline;
import com.sun.tools.xjc.outline.Outline;
import com.sun.tools.xjc.util.DOMUtils;
import jakarta.xml.bind.annotation.XmlTransient;
import org.jvnet.jaxb.plugin.map_init.InitClass;
import org.jvnet.jaxb.plugin.util.FieldOutlineUtils;
import org.jvnet.jaxb.util.CustomizationUtils;
import org.xml.sax.ErrorHandler;

import java.beans.PropertyChangeListener;
Expand All @@ -23,6 +29,7 @@
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
* This Plugin will generate property change events on each setXXX.
Expand Down Expand Up @@ -73,29 +80,30 @@ public boolean run(Outline model, Options opt, ErrorHandler errorHandler) {
interfaceName = globalInterfaceSetting;
}
if (VetoableChangeListener.class.getName().equals(interfaceName)) {
addSupport(VetoableChangeListener.class, VetoableChangeSupport.class, co.implClass);
addSupport(VetoableChangeListener.class, VetoableChangeSupport.class, co);
}
if (PropertyChangeListener.class.getName().equals(interfaceName)) {
addSupport(PropertyChangeListener.class, PropertyChangeSupport.class, co.implClass);
addSupport(PropertyChangeListener.class, PropertyChangeSupport.class, co);
}

}

return true;
}

private void addSupport(Class listener, Class support, JDefinedClass target) {
private void addSupport(Class listener, Class support, ClassOutline classOutline) {

JDefinedClass target = classOutline.implClass;
// add the support field.
// JFieldVar field = target.field(JMod.PRIVATE|JMod.TRANSIENT, support, "support");
JFieldVar field = target.field(JMod.PRIVATE, support, "support");
JFieldVar fieldSupport = target.field(JMod.PRIVATE, support, "support");

field.annotate(XmlTransient.class);
fieldSupport.annotate(XmlTransient.class);

// and initialize it....
field.init(JExpr.direct("new " + support.getSimpleName() + "(this)"));
fieldSupport.init(JExpr.direct("new " + support.getSimpleName() + "(this)"));

// we need to hadd
// we need to add
for (Method method : support.getMethods()) {
if (Modifier.isPublic(method.getModifiers())) {
if (method.getName().startsWith("add")) {
Expand All @@ -118,6 +126,38 @@ private void addSupport(Class listener, Class support, JDefinedClass target) {
}
}
}

final FieldOutline[] declaredFields = classOutline.getDeclaredFields();
for (final FieldOutline fieldOutline : declaredFields) {

final String publicName = fieldOutline.getPropertyInfo().getName(true);

final String setterName = "set" + publicName;

final JType rawType = fieldOutline.getRawType();
final JMethod boxifiedSetter = target.getMethod(setterName, new JType[] { rawType.boxify() });
final JMethod unboxifiedSetter = target.getMethod(setterName, new JType[] { rawType.unboxify() });
final JMethod setter = boxifiedSetter != null ? boxifiedSetter : unboxifiedSetter;

if (setter != null) {
final String privateName = fieldOutline.getPropertyInfo().getName(false);
final JFieldVar field = target.fields().get(privateName);
if (field != null) {
/*
* String oldValue = this.value;
* this.value = newValue;
* this.pcs.firePropertyChange("value", oldValue, newValue);
*/
setter.body().pos(0);

final JVar oldPropertyValue = setter.body().decl(JMod.FINAL,
rawType, "old" + publicName,
field);
setter.body().pos(setter.body().getContents().size());
setter.body().add(fieldSupport.invoke("firePropertyChange").arg(privateName).arg(oldPropertyValue).arg(field));
}
}
}
}

private void addMethod(Method method, JDefinedClass target) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
package org.jvnet.jaxb.tests.propertylistenerinjector;

import generated.Address;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class AddressTest {

@Test
public void testAddress() {
List<PropertyChangeEvent> events = new ArrayList<>();

Address a = new Address();
// just checking new methods have been added
a.addPropertyChangeListener(null);
a.removePropertyChangeListener(null);
a.setStreet("Dollar Lane");
a.setCity("Los Angeles");

a.addPropertyChangeListener("street", events::add);
a.setStreet("Penny Lane");
a.setCity("New York");
Assertions.assertEquals(1, events.size());
PropertyChangeEvent e = events.get(0);
Assertions.assertEquals("Dollar Lane", e.getOldValue());
Assertions.assertEquals("Penny Lane", e.getNewValue());
Assertions.assertEquals("street", e.getPropertyName());
}
}
Loading