Unable to serialize property [OpenApi maven codgen plugin] - java

i'm using "openapi-generator-maven-plugin" version 6.2.1 for generate modules from a YAML file and consume a RestAPI.
The code that is generated from the plugin looks fine and it work great with "GET" requests, the problem that i've encountered so far, is on "POST" requests. Apparently when I pass an object with null values (even if they are nullable) it throws "Unable to serialize property" from [org.eclipse.yasson.internal.Marshaller], even if the object is Serializable.
More specific:
I've this object generated from the plugin.
/*
* MS00140
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package org.openapitools.client.model;
import java.util.Objects;
import java.util.Arrays;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.annotation.JsonValue;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.openapitools.jackson.nullable.JsonNullable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.openapitools.jackson.nullable.JsonNullable;
import java.util.NoSuchElementException;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeName;
/**
* ModelFile
*/
#JsonPropertyOrder({
ModelFile.JSON_PROPERTY_LINK,
ModelFile.JSON_PROPERTY_NAME,
ModelFile.JSON_PROPERTY_MIME_TYPE,
ModelFile.JSON_PROPERTY_DATA
})
#JsonTypeName("File")
#javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2022-11-21T13:50:57.834020300+01:00[Europe/Berlin]")
public class ModelFile implements Serializable {
private static final long serialVersionUID = 1L;
public static final String JSON_PROPERTY_LINK = "link";
private JsonNullable<String> link = JsonNullable.<String>undefined();
public static final String JSON_PROPERTY_NAME = "name";
private JsonNullable<String> name = JsonNullable.<String>undefined();
public static final String JSON_PROPERTY_MIME_TYPE = "mimeType";
private JsonNullable<String> mimeType = JsonNullable.<String>undefined();
public static final String JSON_PROPERTY_DATA = "data";
private JsonNullable<byte[]> data = JsonNullable.<byte[]>undefined();
public ModelFile() {
}
public ModelFile link(String link) {
this.link = JsonNullable.<String>of(link);
return this;
}
/**
* Get link
* #return link
**/
#javax.annotation.Nullable
#ApiModelProperty(value = "")
#JsonIgnore
public String getLink() {
return link.orElse(null);
}
#JsonProperty(JSON_PROPERTY_LINK)
#JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public JsonNullable<String> getLink_JsonNullable() {
return link;
}
#JsonProperty(JSON_PROPERTY_LINK)
public void setLink_JsonNullable(JsonNullable<String> link) {
this.link = link;
}
public void setLink(String link) {
this.link = JsonNullable.<String>of(link);
}
public ModelFile name(String name) {
this.name = JsonNullable.<String>of(name);
return this;
}
/**
* Get name
* #return name
**/
#javax.annotation.Nullable
#ApiModelProperty(value = "")
#JsonIgnore
public String getName() {
return name.orElse(null);
}
#JsonProperty(JSON_PROPERTY_NAME)
#JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public JsonNullable<String> getName_JsonNullable() {
return name;
}
#JsonProperty(JSON_PROPERTY_NAME)
public void setName_JsonNullable(JsonNullable<String> name) {
this.name = name;
}
public void setName(String name) {
this.name = JsonNullable.<String>of(name);
}
public ModelFile mimeType(String mimeType) {
this.mimeType = JsonNullable.<String>of(mimeType);
return this;
}
/**
* Get mimeType
* #return mimeType
**/
#javax.annotation.Nullable
#ApiModelProperty(value = "")
#JsonIgnore
public String getMimeType() {
return mimeType.orElse(null);
}
#JsonProperty(JSON_PROPERTY_MIME_TYPE)
#JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public JsonNullable<String> getMimeType_JsonNullable() {
return mimeType;
}
#JsonProperty(JSON_PROPERTY_MIME_TYPE)
public void setMimeType_JsonNullable(JsonNullable<String> mimeType) {
this.mimeType = mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = JsonNullable.<String>of(mimeType);
}
public ModelFile data(byte[] data) {
this.data = JsonNullable.<byte[]>of(data);
return this;
}
/**
* Get data
* #return data
**/
#javax.annotation.Nullable
#ApiModelProperty(value = "")
#JsonIgnore
public byte[] getData() {
return data.orElse(null);
}
#JsonProperty(JSON_PROPERTY_DATA)
#JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
public JsonNullable<byte[]> getData_JsonNullable() {
return data;
}
#JsonProperty(JSON_PROPERTY_DATA)
public void setData_JsonNullable(JsonNullable<byte[]> data) {
this.data = data;
}
public void setData(byte[] data) {
this.data = JsonNullable.<byte[]>of(data);
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ModelFile _file = (ModelFile) o;
return equalsNullable(this.link, _file.link) &&
equalsNullable(this.name, _file.name) &&
equalsNullable(this.mimeType, _file.mimeType) &&
equalsNullable(this.data, _file.data);
}
private static <T> boolean equalsNullable(JsonNullable<T> a, JsonNullable<T> b) {
return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get()));
}
#Override
public int hashCode() {
return Objects.hash(hashCodeNullable(link), hashCodeNullable(name), hashCodeNullable(mimeType), hashCodeNullable(data));
}
private static <T> int hashCodeNullable(JsonNullable<T> a) {
if (a == null) {
return 1;
}
return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ModelFile {\n");
sb.append(" link: ").append(toIndentedString(link)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" mimeType: ").append(toIndentedString(mimeType)).append("\n");
sb.append(" data: ").append(toIndentedString(data)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
When I make the request the only property that I set for the moment is the "link" property, because the REST service knows what to do.
public File getFileByLink(String link) throws WebServiceException, DataNotFoundException {
log.debug("Executing---> getFileByLink()");
File file;
try {
ModelFile inputFile = new ModelFile();
inputFile.setLink(link);
file = utilityApi.apiUtilityGetFileByLinkPost(inputFile);
if (file == null) {
throw new DataNotFoundException("Error!");
}
} catch (ApiException e) {
throw new WebServiceException(e.getCode() + " - " + e.getMessage());
} catch (DataNotFoundException e) {
throw e;
} catch (Exception e) {
throw new WebServiceException(e);
}
log.debug("Leaving ---> getFileByLink()");
return file;
}
Now when it perform the actual request and try to serialize the object throws this error:
13:55:36,124 SEVERE [org.eclipse.yasson.internal.Marshaller] (default task-1) Unable to serialize property 'data_JsonNullable' from org.openapitools.client.model.ModelFile
13:55:36,133 SEVERE [org.eclipse.yasson.internal.Marshaller] (default task-1) Generating incomplete JSON
13:55:36,145 ERROR [it.inps.itg.web.exception.WebServiceException] (default task-1) WebServiceException in Class: TemplateAction.java and Method: executeAction Message: RESTEASY004655: Unable to invoke request: javax.ws.rs.ProcessingException: RESTEASY008205: JSON Binding serialization error javax.json.bind.JsonbException: Unable to serialize property 'data_JsonNullable' from org.openapitools.client.model.ModelFile Cause: javax.ws.rs.ProcessingException: RESTEASY008205: JSON Binding serialization error javax.json.bind.JsonbException: Unable to serialize property 'data_JsonNullable' from org.openapitools.client.model.ModelFile
At first I didn't use the property <serializableModel>true</serializableModel>, and I thought that the object could not be searialized for this problem, but even if the class implement the Serializable interface the problem still occur.
If can help, I've tried to set values to all the object's properties and as long as they are not null, there's non serialization problems. The problem occur when there's at least one property that is null.

Related

Trying to figure out unexplained error with JUnit tests and model object

I am working on modeling several java objects that manage entities in a mySQL database using the JDBCTemplate.
I have run Add/Get JUnit tests on two other objects and I am not getting any errors, but I cannot figure out what is causing this error for my 'Organization' object.
Here is my 'Organization' dto code:
package com.sg.superherosightings.model;
import java.util.Objects;
public class Organization {
private int orgId;
private String orgName;
private String orgDescription;
private String orgPhone;
private String orgEmail;
private String orgStreetAddress;
private String orgCity;
private String orgState;
private String orgZipCode;
public int getOrgId() {
return orgId;
}
public void setOrgId(int orgId) {
this.orgId = orgId;
}
public String getOrgName() {
return orgName;
}
public void setOrgName(String orgName) {
this.orgName = orgName;
}
public String getOrgDescription() {
return orgDescription;
}
public void setOrgDescription(String orgDescription) {
this.orgDescription = orgDescription;
}
public String getOrgPhone() {
return orgPhone;
}
public void setOrgPhone(String orgPhone) {
this.orgPhone = orgPhone;
}
public String getOrgEmail() {
return orgEmail;
}
public void setOrgEmail(String orgEmail) {
this.orgEmail = orgEmail;
}
public String getOrgStreetAddress() {
return orgStreetAddress;
}
public void setOrgStreetAddress(String orgStreetAddress) {
this.orgStreetAddress = orgStreetAddress;
}
public String getOrgCity() {
return orgCity;
}
public void setOrgCity(String orgCity) {
this.orgCity = orgCity;
}
public String getOrgState() {
return orgState;
}
public void setOrgState(String orgState) {
this.orgState = orgState;
}
public String getOrgZipCode() {
return orgZipCode;
}
public void setOrgZipCode(String orgZipCode) {
this.orgZipCode = orgZipCode;
}
#Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + this.orgId;
hash = 89 * hash + Objects.hashCode(this.orgName);
hash = 89 * hash + Objects.hashCode(this.orgDescription);
hash = 89 * hash + Objects.hashCode(this.orgPhone);
hash = 89 * hash + Objects.hashCode(this.orgEmail);
hash = 89 * hash + Objects.hashCode(this.orgStreetAddress);
hash = 89 * hash + Objects.hashCode(this.orgCity);
hash = 89 * hash + Objects.hashCode(this.orgState);
hash = 89 * hash + Objects.hashCode(this.orgZipCode);
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Organization other = (Organization) obj;
if (this.orgId != other.orgId) {
return false;
}
if (!Objects.equals(this.orgName, other.orgName)) {
return false;
}
if (!Objects.equals(this.orgDescription, other.orgDescription)) {
return false;
}
if (!Objects.equals(this.orgPhone, other.orgPhone)) {
return false;
}
if (!Objects.equals(this.orgEmail, other.orgEmail)) {
return false;
}
if (!Objects.equals(this.orgStreetAddress, other.orgStreetAddress)) {
return false;
}
if (!Objects.equals(this.orgCity, other.orgCity)) {
return false;
}
if (!Objects.equals(this.orgState, other.orgState)) {
return false;
}
if (!Objects.equals(this.orgZipCode, other.orgZipCode)) {
return false;
}
return true;
}
}
Here is my Mapper Method in my DaoDBImpl:
img of OrgMapper Method before fix
This is my SuperSightings_DaoTest method causing the error:
package com.sg.superherosightings.dao;
import com.sg.superherosightings.model.Location;
import com.sg.superherosightings.model.Organization;
import com.sg.superherosightings.model.Power;
import com.sg.superherosightings.model.Sighting;
import com.sg.superherosightings.model.Supe;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SuperSightings_DaoTest {
SuperSightings_Dao dao;
public SuperSightings_DaoTest() {
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
ApplicationContext ctx
= new ClassPathXmlApplicationContext("test-applicationContext.xml");
dao = ctx.getBean("SuperSightings_Dao", SuperSightings_Dao.class);
// delete all supes
List<Supe> supes = dao.getAllSupes(); for (Supe currentSupe : supes) {
dao.deleteSupe(currentSupe.getSupeId());
}
// delete all powers
List<Power> powers = dao.getAllPowers(); for (Power currentPower : powers) {
dao.deletePower(currentPower.getPowerId());
}
//delete all organizations
List<Organization> orgs = dao.getAllOrganizations(); for (Organization currentOrg : orgs) {
dao.deleteOrganization(currentOrg.getOrgId());
}
// delete all locations
List<Location> locations = dao.getAllLocations(); for (Location currentLocation : locations) {
dao.deleteLocation(currentLocation.getLocationId());
}
// delete all sightings
List<Sighting> sightings = dao.getAllSightings(); for (Sighting currentSighting : sightings) {
dao.deleteSighting(currentSighting.getSightingId());
}
}
#After
public void tearDown() {
}
/**
* Test of addPower method, of class SuperSightings_Dao.
*/
#Test
public void testAddGetPower() {
Power power = new Power();
power.setPowerType("Fire");
power.setPowerDescription("Shoots fire from hands");
dao.addPower(power);
Power fromDao = dao.getPowerById(power.getPowerId());
assertEquals(fromDao, power);
}
/**
* Test of deletePower method, of class SuperSightings_Dao.
*/
#Test
public void testDeletePower() {
Power power = new Power();
power.setPowerType("Fire");
power.setPowerDescription("Shoots fire from hands");
dao.addPower(power);
Power fromDao = dao.getPowerById(power.getPowerId());
assertEquals(fromDao, power);
dao.deletePower(power.getPowerId());
assertNull(dao.getPowerById(power.getPowerId()));
}
/**
* Test of getAllPowersBySupeId method, of class SuperSightings_Dao.
*/
#Test
public void testGetAllPowersBySupeId() {
}
/**
* Test of addOrganization method, of class SuperSightings_Dao.
*/
#Test
public void testAddGetOrganization() {
Organization org = new Organization();
org.setOrgName("Legion of Doom");
org.setOrgDescription("evil organization");
org.setOrgPhone("333-444-5678");
org.setOrgEmail("lod#evil.org");
org.setOrgStreetAddress("344 Lowland Blvd.");
org.setOrgCity("Quahog");
org.setOrgState("RI");
org.setOrgZipCode("09678");
dao.addOrganization(org);
Organization fromDao = dao.getOrganizationById(org.getOrgId());
assertEquals(fromDao, org); //this is the line causing the error
}
This is the error I am getting:
testAddGetOrganization(com.sg.superherosightings.dao.SuperSightings_DaoTest)
Time elapsed: 0.107 sec <<< FAILURE! java.lang.AssertionError:
expected:com.sg.superherosightings.model.Organization#ae511546 but
was:com.sg.superherosightings.model.Organization#15fabf0f
Please let me know if I need to provide further information. i am trying to get better at how i post questions here. I searched for a long time before asking but all I can find is that it might be something with my equals/hash code. I'm just not sure what is getting changed when the comparison is made because it is not happening with my other objects.
Thank you for any hints, and please don't bite my head off!
It seems some fields are not equal. try to compare all fields one by one to identify non-equal fields: assertEquals(fromDao.getOrgId(), org.getOrgId() and all the rest of organization's fields)
Thank you all for your assistance! I was able to convert my org and fromDao objects to string to see them in the test window. The problem was with my Mapper method for the Organization object. See original and the fix below:
Original Version
private static final class OrgMapper implements RowMapper<Organization> {
#Override
public Organization mapRow(ResultSet rs, int i) throws SQLException {
Organization org = new Organization();
org.setOrgId(rs.getInt("org_id"));
org.setOrgName(rs.getString("org_name"));
org.setOrgDescription(rs.getString("org_description"));
org.setOrgPhone(rs.getString("org_phone"));
org.setOrgEmail(rs.getString("org_street_address")); //wrong field
org.setOrgCity(rs.getString("org_city"));
org.setOrgState(rs.getString("org_state"));
org.setOrgZipCode(rs.getString("org_zip_code"));
return org;
}
}
Fixed OrgMapper:
private static final class OrgMapper implements RowMapper<Organization> {
#Override
public Organization mapRow(ResultSet rs, int i) throws SQLException {
Organization org = new Organization();
org.setOrgId(rs.getInt("org_id"));
org.setOrgName(rs.getString("org_name"));
org.setOrgDescription(rs.getString("org_description"));
org.setOrgPhone(rs.getString("org_phone"));
org.setOrgEmail(rs.getString("org_email"));
org.setOrgStreetAddress(rs.getString("org_street_address"));
org.setOrgCity(rs.getString("org_city"));
org.setOrgState(rs.getString("org_state"));
org.setOrgZipCode(rs.getString("org_zip_code"));
return org;
}

How to check requested GraphQL fields in Java with fragments?

I have a GraphQL query similar to this:
query {
getPosts {
...PostFragment
}
}
fragment SpecificPostFragment on SpecificPost {
owner {
id
name
}
}
fragment PostFragment on Post {
id
object
... on SpecificPost {
...SpecificPostFragment
}
}
I try to know if:
the field object is requested
the field owner is requested
I try to apply what is written here:
https://www.graphql-java.com/documentation/v11/fieldselection/
But dataFetchingEnvironment.getSelectionSet().contains("XXX") does not seem to work well with fragments.
How to do that ?
I haven't found any built-in solution, so I wrote my own. Here is my code
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import graphql.execution.MergedField;
import graphql.language.Field;
import graphql.language.FragmentDefinition;
import graphql.language.FragmentSpread;
import graphql.language.InlineFragment;
import graphql.language.SelectionSet;
import graphql.schema.DataFetchingEnvironment;
public class GraphQLUtil {
private static class PathElement {
private final String name;
private final String typeName;
public PathElement(String name, String typeName) {
this.name = name;
this.typeName = typeName;
}
public String getName() {
return name;
}
public String getTypeName() {
return typeName;
}
}
public static boolean containsIncludingFragments(DataFetchingEnvironment env, String path) {
Objects.requireNonNull(env, "The data fetching environment must not be null");
Objects.requireNonNull(path, "The field path must not be null");
List<PathElement> elts = Stream.of(path.split("/")).map(p -> {
String pt = p.trim();
if (pt.isEmpty()) {
throw new IllegalArgumentException("Empty path element found");
}
int sepIdx = pt.indexOf(":");
String name = pt;
String typeName = null;
if (sepIdx >= 0) {
typeName = pt.substring(0, sepIdx);
name = pt.substring(sepIdx + 1, pt.length());
}
return new PathElement(name, typeName);
}).collect(Collectors.toList());
if (elts.isEmpty()) {
return false;
}
MergedField mf = env.getMergedField();
return searchPathElement(env, elts, 0, mf.getSingleField().getSelectionSet(), null);
}
private static boolean searchPathElement(
DataFetchingEnvironment env,
List<PathElement> elts,
int eltIndex,
SelectionSet selectionSet,
String selectionTypeName) {
if (eltIndex >= elts.size()) {
return true;
}
PathElement currentElt = elts.get(eltIndex);
String currentName = currentElt.getName();
String currentTypeName = currentElt.getTypeName();
List<Field> fields = selectionSet.getSelectionsOfType(Field.class);
boolean found = false;
for (Field f : fields) {
if (f.getName().equals(currentName) && (currentTypeName == null
|| selectionTypeName == null
|| currentTypeName.equals(selectionTypeName))) {
found = searchPathElement(env, elts, eltIndex + 1, f.getSelectionSet(), null);
if (found) {
return true;
}
}
}
List<FragmentSpread> fragments = selectionSet.getSelectionsOfType(FragmentSpread.class);
for (FragmentSpread f : fragments) {
FragmentDefinition fDef = env.getFragmentsByName().get(f.getName());
found = searchPathElement(env, elts, eltIndex, fDef.getSelectionSet(), fDef.getTypeCondition().getName());
if (found) {
return true;
}
}
List<InlineFragment> inlineFragments = selectionSet.getSelectionsOfType(InlineFragment.class);
for (InlineFragment f : inlineFragments) {
found = searchPathElement(env, elts, eltIndex, f.getSelectionSet(), f.getTypeCondition().getName());
if (found) {
return true;
}
}
return false;
}
}
And you call it like this:
DataFetchingEnvironment dataEnv = ... // If like me you use GraphQL SPQR, you can get it with io.leangen.graphql.execution.ResolutionEnvironment
boolean t1= GraphQLUtil.containsIncludingFragments(dataEnv, "id");
boolean t2 = GraphQLUtil.containsIncludingFragments(dataEnv, "owner/id");
boolean t3 = GraphQLUtil.containsIncludingFragments(dataEnv, "SpecificPost:owner/id"); // You may give the type of the field, if in some inheritance scenario, it is ambiguous
Note that this solution does not support wild card (* or ?). And I haven't tested it if the main query contains multiple entries (getPost + getPeople in the same query for example), but that probably does not work in that case.

How to find all references to a method programmatically?

So, this isn't how to find method references using Eclipse IDE.
I need to find them via code (Java).
Background:
We have hundreds of projects, all based off a common project. Over the years, the common project has some really bad code that has been replaced. The bad code has been marked as Deprecated.
Now, I want to remove all the deprecated code. But, I want to create some code to migrate all the other projects we have.
Approach:
Now, for some things, I could search the project code for some keywords (i.e method name) and replace with something else. However, there are some method names that would collide and doing a simple search/replace would not work.
My thought is, if I have a deprecated method:
com.foo.bar.SomeClass.someMethod(String)
Then some way to find every place that someMethod(String) is used, I could then replace that one with newMethod(String)
I have looked some at:
org.reflections.Reflections
ASM
Basically, I want to create a migration program to make migrating to the new common code simple. I plan to use this same migration code to help migrate the projects from JDK8 to OpenJDK11.
Thoughts on how I can accomplish this?
You can certainly use ASM with a ClassVisitor / MethodVisitor to find all references to this method.
You just have to override visitMethod in the ClassVisitor to return your own MethodVisitor, and in the MethodVisitor override visitMethodInsn.
In the visitMethodInsn you check if the target is one of the deprecated methods, and log where it is used. Here an example:
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import static org.objectweb.asm.Opcodes.*;
public class MethodScanner extends ClassVisitor {
private final String fileName;
private MethodScanner(String fileName) {
super(ASM7);
this.fileName = fileName;
}
public static void main(String[] args) throws IOException {
scanJar(new File("path/to/some.jar"));
}
public static void scanJar(File jarFile) throws IOException {
var jf = new JarFile(jarFile);
jf.stream().filter(je -> getFileExtension(je.getName()).equals(".class"))
.forEach(je -> processEntry(jf, je));
}
private static String getFileExtension(String name) {
int idx = name.lastIndexOf(".");
if (idx == -1)
return "";
return name.substring(idx);
}
private static void processEntry(JarFile jf, JarEntry je) {
try {
byte[] bytes = jf.getInputStream(je).readAllBytes();
MethodScanner ms = new MethodScanner(jf.getName() + "!" + je.getName());
ClassReader cr = new ClassReader(bytes);
cr.accept(ms, 0);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
#Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,
String[] exceptions) {
return new MethodScannerVisitor(super.visitMethod(access, name, descriptor, signature, exceptions), fileName, name + descriptor);
}
private static class MethodScannerVisitor extends MethodVisitor {
private final String fileName;
private final String methodName;
private MethodScannerVisitor(MethodVisitor parent, String fileName, String methodName) {
super(ASM7, parent);
this.fileName = fileName;
this.methodName = methodName;
}
#Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
if (owner.equals("java/lang/Math") && name.equals("random") && descriptor.equals("()D")) {
System.out.println("reference to Math.random() from " + fileName + " in " + methodName);
}
}
}
}
Doing some searching, I have some base code, but still not going 100%
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class ProjectMigration {
public static void main (String[] args) {
ProjectMigration migration = new ProjectMigration();
try {
migration.migrate();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
private List<DeprecatedClass> getDeprecatedMethods () {
List<DeprecatedClass> deprecatedClasses = new ArrayList<>();
deprecatedClasses.add(
new DeprecatedClass("com.e2open.selenium.api_common.abstractHelpers.SystemInformation",
"isInternetExplorer8", "boolean", ""));
deprecatedClasses.add(
new DeprecatedClass("com.e2open.selenium.api_common.AbstractPage", "radioButtonSelect",
"boolean", "java.lang.String", "java.lang.String"));
return deprecatedClasses;
}
public void migrate ()
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
List<DeprecatedClass> deprecatedClasses = getDeprecatedMethods();
for (DeprecatedClass clazz : deprecatedClasses) {
System.out.println("CLASS: " + clazz.getClazz());
Class c = Class.forName(clazz.getClazz());
analyze(c.newInstance(), clazz);
System.out.println();
}
}
private void analyze (Object object, DeprecatedClass deprecatedClass) {
ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
#Override
public MethodVisitor visitMethod (
int access, String name, String desc, String signature, String[] exceptions) {
if (isDeprecatedMethod(deprecatedClass, name, desc)) {
logMethod(name, desc);
return new MethodVisitor(Opcodes.ASM5) {
#Override
public void visitMethodInsn (
int opcode, String owner, String name, String desc, boolean arg4) {
if (owner.contains("e2open")) {
processMethod(owner, name, desc);
}
super.visitMethodInsn(opcode, owner, name, desc, arg4);
}
};
}
return null;
}
};
try {
ClassReader classReader = new ClassReader(object.getClass().getCanonicalName());
classReader.accept(cv, 0);
} catch (IOException e) {
System.err.println("Something went wrong !! " + e.getMessage());
}
}
protected void processMethod (String owner, String name, String desc) {
System.out.println(
"classUsed[" + owner.replace("/", ".") + "]; methodUsed[" + name + "]; methodParameters["
+ desc + "]");
}
protected void logMethod (String name, String desc) {
String returnType = getReturnType(desc);
String paramters = getParamters(desc);
System.out.println(String.format("METHOD: %s %s(%s)", returnType, name, paramters));
}
private String getParamters (String desc) {
String parms = desc.split("\\)")[0];
if (parms.equals("(")) {
return "";
}
parms = parms.substring(2, parms.length());
String[] parmameters = parms.split(";");
StringBuilder paramterString = new StringBuilder();
for (String p : parmameters) {
paramterString.append(p.replaceAll("/", ".")).append(", ");
}
return paramterString.toString().substring(0, paramterString.length() - 2);
}
private String getReturnType (String desc) {
String returnType = desc.split("\\)")[1];
if (returnType.equals("V")) {
return "void";
}
if (returnType.length() == 1) {
return returnType;
}
return returnType.substring(1, returnType.length() - 1).replace("/", ".");
}
private boolean isDeprecatedMethod (
DeprecatedClass deprecatedClass, String method, String parmeters) {
if ((method.equals(deprecatedClass.getMethod()))
&& (parmeters.equals(deprecatedClass.getParameters()))) {
return true;
}
return false;
}
private class DeprecatedClass {
private String clazz;
private String method;
private List<String> parameters;
private String returnType;
public DeprecatedClass() {}
/**
* No paramters and no return type
*
* #param clazzName The class to check. Example: com.e2open.selenium.api_common.AbstractPage
* #param methodName The method name to find references for. Example: clearAllInputFields
*/
public DeprecatedClass(String clazzName, String methodName) {
this.clazz = clazzName;
this.method = methodName;
}
/**
* Use if there is a return type and/or parameters
*
* #param clazzName The class to check. Example: com.e2open.selenium.api_common.AbstractPage
* #param methodName he method name to find references for. Example: findFieldByAttribute
* #param returnType The returned type. Example: org.openqa.selenium.By
* #param parameterValues List of paramters. Example: "java.lang.String", "java.lang.String",
* "java.lang.String"
*/
public DeprecatedClass(String clazzName, String methodName, String returnType,
String... parameterValues) {
this.clazz = clazzName;
this.method = methodName;
setReturnType(returnType);
if (parameterValues != null) {
for (String parm : parameterValues) {
if (StringUtils.isNoneBlank(parm)) {
addParameter(parm);
}
}
}
}
/**
* #return the clazz
*/
public String getClazz () {
return clazz;
}
/**
* #param clazz the clazz to set
*/
public void setClazz (String clazz) {
this.clazz = clazz;
}
/**
* #return the method
*/
public String getMethod () {
return method;
}
/**
* #param method the method to set
*/
public void setMethod (String method) {
this.method = method;
}
/**
* #param returnType the returnType to set
*/
public void setReturnType (String returnType) {
if (returnType != null) {
if ("boolean".equals(returnType)) {
this.returnType = "Z";
} else {
this.returnType = "L" + returnType.replaceAll("\\.", "/") + ";";
}
}
}
/**
* #return the parameters
*/
public String getParameters () {
StringBuilder parms = new StringBuilder();
if (this.parameters == null) {
parms.append("()");
} else {
parms.append("(").append(String.join("", this.parameters)).append(")");
}
if (this.returnType == null) {
parms.append("V");
} else {
parms.append(this.returnType);
}
return parms.toString();
}
/**
* #param parameters the parameters to set
*/
public void addParameter (String parameter) {
if (this.parameters == null) {
this.parameters = new ArrayList<>();
}
this.parameters.add("L" + parameter.replaceAll("\\.", "/") + ";");
}
}
}
The results I get is:
CLASS: com.e2open.selenium.api_common.abstractHelpers.SystemInformation
METHOD: Z isInternetExplorer8()
classUsed[com.e2open.selenium.api_common.abstractHelpers.SystemInformation]; methodUsed[getSystemData]; methodParameters[()Lcom/e2open/selenium/api_common/abstractHelpers/SystemInformation$SystemData;]
classUsed[com.e2open.selenium.api_common.browser.BrowserType]; methodUsed[equals]; methodParameters[(Ljava/lang/Object;)Z]
CLASS: com.e2open.selenium.api_common.AbstractPage
METHOD: Z radioButtonSelect(java.lang.String, Ljava.lang.String)
classUsed[com.e2open.selenium.api_common.JLog]; methodUsed[write]; methodParameters[(Ljava/lang/String;)V]
classUsed[com.e2open.selenium.api_common.AbstractPage]; methodUsed[radioButtonGet]; methodParameters[(Ljava/lang/String;Ljava/lang/String;)Lorg/openqa/selenium/WebElement;]
However, the results are not correct.
If I take one of the methods:
com.e2open.selenium.api_common.abstractHelpers.SystemInformation.isInternetExplorer8()
And use Eclipse to find References, I get
isInternetExplorer8 Eclipse References Image
And for the other method doing a search on:
com.e2open.selenium.api_common.AbstractPage.radioButtonSelect(String, String)
radioButtonSelect Eclipse Reference Image
I am unsure what to change or where to go from here.

jsp checkbox value not binding

I have a problem in getting checkbox's value from JSP.
I used SpringMVC, and my related class as follows:
Form:
#Getter #Setter
public class Sample3Form extends AbstractForm {<
private List<Sample1Bean> sampleList; //all data
private ValidPagedListHolder<Sample1Bean> samplePagedList;//1 page data
}
the class to control changing page:
ValidPagedListHolder:
#SuppressWarnings("serial")
public class ValidPagedListHolder<E> extends PagedListHolder<E> implements
Serializable {
...
...
/**
* Return a sub-list representing the current page.
*/
#Override
#Valid
public List<E> getPageList() {
return super.getPageList();
}
/**
* コンストラクタ生成時の初期化処理を行うメソッド
*/
protected void init() {
setPageSize(DEFAULT_PAGE_SIZE);
}
}
Sample1Bean:
#Getter #Setter
public class Sample1Bean extends AbstractOnlineDataBean {
private String keiyakuno;
private String keiyakunm;
private String torisakino;
}
Parent Bean Class:
#Getter
#Setter
public abstract class AbstractOnlineDataBean extends AbstractDataBean {
private Integer selectedIndex;
private String maskPattern;
}
Controller:
#Controller
#RequestMapping(value = "app/sample3")
#SessionAttributes(value = "sample3Form")
#NotCheckToken
public class SampleController3 extends AbstractController {
private static Logger logger = LoggerFactory.getLogger(UserUtil.class);
#ModelAttribute(value = "sample3Form")
public Sample3Form getForm() {
return new Sample3Form();
}
......
......
#RequestMapping(value = "delete")
public String delete(Model model, #Validated Sample3Form form, BindingResult result, HttpServletRequest request) throws GdcSystemException {
List<Sample1Bean> list = new ArrayList<Sample1Bean>();
int size = form.getSampleList().size();
ValidPagedListHolder<Sample1Bean> plist = form.getSamplePagedList();
list = plist.getPageList();
for (int i = 0 ; i < size; i ++) {
if (form.getSampleList().get(i).getSelectedIndex() == null ) {
} else {
//I cannot arrive here even though I checked in JSP
list.add(form.getSampleList().get(i));
}
}
...
...
}
JSP:
<ab:form id="sample3" action="submit" modelAttribute="sample3Form">
<table width="100%" class="tableborder" cellpadding="0" cellspacing="0">
...
...
<ab:tr index="${row.index}">
<td width="2%" class="data_list_area">
<ab:checkbox path="${sample3Form.samplePagedList.pageList[row.index].selectedIndex}" fwformat='NONE'
value="${sample3Form.samplePagedList.page * sample3Form.samplePagedList.pageSize + row.index }" name="checkedids"/>
</td>
<td width="5%" class="data_list_area">
<!--ab:out value="${sample3Form.samplePagedList.pageList[row.index].keiyakuno}" /-->
<ab:label path="" fwformat='NONE'>${sample3Form.samplePagedList.pageList[row.index].keiyakuno}</ab:label>
</td>
...
...
In above JSP, I set checkboxes and bind the checkboxes to selectedIndex property for for every row data.but i cannot get selected row in controller as follows:
form.getSampleList().get(i).getSelectedIndex()
The return value is always null.
why? Could who please tell me how i can get the selectedIndex in controller?
By the way, I can get checked row in controller like below:
String[] arr = request.getParameterValues("checkedids");
Remarks: in JSP, These added checkboxes is defined by name "checkedids".
and <ab:checkbox> is a tag class extends AbstractSingleCheckedElementTag.
the src for CheckboxTagImpl is here:
public class CheckboxTagImpl extends AbstractSingleCheckedElementTag {
private String maskPatterns = null;
private boolean escapeMaskFlg = false;
/**
*
* #return
*/
public String getMaskPatterns() {
return maskPatterns;
}
/**
*
* #param maskPatterns
*/
public void setMaskPatterns(String maskPatterns) {
this.maskPatterns = maskPatterns;
}
/**
* #return
*/
public Boolean isEscapeMaskFlg() {
return escapeMaskFlg;
}
/**
* #param escapeMaskFlg
*/
public void setEscapeMaskFlg (Boolean escapeMaskFlg) {
this.escapeMaskFlg = escapeMaskFlg;
}
#Override
protected int writeTagContent(TagWriter tagWriter) throws JspException {
if (maskPatterns != null) {
FormTagImpl formTag = TagUtil.getFormTag(this);
String formClassName = formTag.getModelAttribute();
String maskPattern = TagUtil.getMaskPattern(formClassName, pageContext);
if (maskPattern != null) {
String[] maskPatternArray = maskPatterns.split(",");
for (int i = 0; i < maskPatternArray.length; i++) {
if (maskPattern.equals(maskPatternArray[i])) {
setDisabled(true);
break;
}
}
}
}
FormTagImpl formTag = TagUtil.getFormTag(this);
String formClassName = formTag.getModelAttribute();
Boolean maskFlg = TagUtil.getMaskFlg(formClassName, pageContext);
if (maskFlg == true && escapeMaskFlg == false) {
setDisabled(true);
}
if (!isDisabled()) {
// Write out the 'field was present' marker.
tagWriter.startTag("input");
tagWriter.writeAttribute("type", "hidden");
String name = WebDataBinder.DEFAULT_FIELD_MARKER_PREFIX + getName();
tagWriter.writeAttribute("id", getId());
tagWriter.writeAttribute("name", name);
tagWriter.writeAttribute("value", processFieldValue(name, SystemConstant.FLAG_OFF, getInputType()));
tagWriter.endTag();
}
super.writeTagContent(tagWriter);
return SKIP_BODY;
}
#Override
protected void writeTagDetails(TagWriter tagWriter) throws JspException {
tagWriter.writeAttribute("type", getInputType());
Object boundValue = getBoundValue();
Class<?> valueType = getBindStatus().getValueType();
if (Boolean.class.equals(valueType) || boolean.class.equals(valueType)) {
// the concrete type may not be a Boolean - can be String
if (boundValue instanceof String) {
boundValue = Boolean.valueOf((String) boundValue);
}
Boolean booleanValue = (boundValue != null ? (Boolean) boundValue : Boolean.FALSE);
renderFromBoolean(booleanValue, tagWriter);
} else if (String.class.equals(valueType) && getValue() == null) {
renderFromValue(SystemConstant.FLAG_ON, tagWriter);
}
else {
Object value = getValue();
if (value == null) {
throw new IllegalArgumentException("Attribute 'value' is required when binding to non-boolean values");
}
Object resolvedValue = (value instanceof String ? evaluate("value", value) : value);
renderFromValue(resolvedValue, tagWriter);
}
}
#Override
public void doFinally() {
if (PropertiesUtil.getProperty("cleanAtDoFinally").equals("true")) {
super.doFinally();
this.maskPatterns = null;
this.escapeMaskFlg = false;
setDisabled(false);
}
}
#Override
protected String getInputType() {
return "checkbox";
}
#Override
protected String getName() throws JspException {
if (getPath()==null) {
return super.getName();
} else {
return getPath();
}
}
#Override
protected BindStatus getBindStatus() throws JspException {
BindStatus bindStatus = null;
if (bindStatus == null) {
// HTML escaping in tags is performed by the ValueFormatter class.
String nestedPath = getNestedPath();
String pathToUse = (nestedPath != null ? nestedPath + getPath() : getPath());
if (pathToUse.endsWith(PropertyAccessor.NESTED_PROPERTY_SEPARATOR)) {
pathToUse = pathToUse.substring(0, pathToUse.length() - 1);
}
bindStatus = new BindStatus(getRequestContext(), pathToUse, false);
}
return bindStatus;
}
}
Thanks.

Getting null data from a JSON object

Essentially, this is the kind of data I want returned:
{
"Top10BidAsks":[
{
"Bid":{
"Price":10.0,
"Size":2.0,
"ExchangeID":"SMART",
"timeStamp":0
},
"Ask":{
"Price":12.0,
"Size":2.0,
"ExchangeID":"SMART",
"timeStamp":0
}
},
{
"Bid":{
"Price":0.0,
"Size":0.0,
"ExchangeID":"SMART",
"timeStamp":0
},
"Ask":{
"Price":13.0,
"Size":12.0,
"ExchangeID":"SMART",
"timeStamp":0
}
}
]
}
The {"Price":10.0,"Size":2.0,"ExchangeID":"SMART","timeStamp":0}, essentially represents a MarketData Object that I've created with those 4 fields.
The main function I'm calling is:
public MarketDataListLevel2 getMarketDataDepth() {
try {
MarketDataListLevel2 md = cs.getMarketDataDepth();
log.info(md.toString());
return md;
}
catch ( Exception e) {
....
}
}
Where cs is just an interface that retrieves the JSON data from a site.
The MarketDataLevel2 object is:
public class MarketDataListLevel2 {
public static class MarketDataList {
public MarketData[] a;
}
public MarketDataList[] listofmarketdatalists;
public MarketDataListLevel2(#JsonProperty("Top10BidAsks") MarketDataList[] listofmarketdatalists) {
this.listofmarketdatalists = listofmarketdatalists;
}
I tried to make this object match the output I want (formatting wise), but apparently I might have a data structure error here, because I'm not getting the data I want returned.
When I run the first method that I listed:
MarketDataListLevel2 a = getDepthMarketData(coin);
When I debug this 'a' object, I see that each element in the listofmarketdatalists array is 'null'
instead of containing an object with this format: {"Bid":{"Price":10.0,"Size":2.0,"ExchangeID":"SMART","timeStamp":0},
"Ask":{"Price":12.0,"Size":2.0,"ExchangeID":"SMART","timeStamp":0}}.
Any advice would be awesome.
You have to create correct POJO classes which represent your JSON. See below example:
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonProgram {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Root root = mapper.readValue(json, Root.class);
System.out.println(root.getTop10());
}
}
class Root {
#JsonProperty("Top10BidAsks")
private List<MarketDataEntity> top10;
public List<MarketDataEntity> getTop10() {
return top10;
}
public void setTop10(List<MarketDataEntity> top10) {
this.top10 = top10;
}
}
class MarketDataEntity {
private Map<String, MarketData> datas = new HashMap<String, MarketData>();
#JsonAnySetter
public void setMarketData(String key, MarketData data) {
datas.put(key, data);
}
#Override
public String toString() {
return datas.toString();
}
}
class MarketData {
#JsonProperty("Price")
private BigDecimal price;
#JsonProperty("Size")
private BigDecimal size;
#JsonProperty("ExchangeID")
private String exchangeId;
private int timeStamp;
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public BigDecimal getSize() {
return size;
}
public void setSize(BigDecimal size) {
this.size = size;
}
public String getExchangeId() {
return exchangeId;
}
public void setExchangeId(String exchangeId) {
this.exchangeId = exchangeId;
}
public int getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(int timeStamp) {
this.timeStamp = timeStamp;
}
#Override
public String toString() {
return "MarketData [price=" + price + ", size=" + size + ", exchangeId=" + exchangeId + ", timeStamp=" + timeStamp + "]";
}
}
Above program prints:
[{Bid=MarketData [price=10.0, size=2.0, exchangeId=SMART, timeStamp=0], Ask=MarketData [price=12.0, size=2.0, exchangeId=SMART, timeStamp=0]}, {Bid=MarketData [price=0.0, size=0.0, exchangeId=SMART, timeStamp=0], Ask=MarketData [price=13.0, size=12.0, exchangeId=SMART, timeStamp=0]}]

Categories

Resources