I try to write code in jade (Java Agent DEvelopment Framework) to print the binary tree of agents in sma. I want to print tree inorder traversal with origin algorithm:
Traverse the left subtree, i.e., call Inorder(left-subtree)
Visit the root.
Traverse the right subtree, i.e., call Inorder(right-subtree)
And my node agent is:
class Noeud {
private Integer value = null;
private AID gauche = null;
private AID droit = null;
private AID pere = null;
}
In my agent to print, I use CyclicBehaviour as extensions. With my code:
public class ReceiveAffichageBehaviour extends CyclicBehaviour{
#Override
public void action() {
MessValueGauche();
MessValue();
MessValueDroit();
}
private void MessValueGauche() {
MessageTemplate messageTemplate = MessageTemplate.and(
MessageTemplate.MatchOntology(Constants.AFFICHAGE_VALUE_GAUCHE),
MessageTemplate.MatchPerformative(ACLMessage.REQUEST)
);
ACLMessage receiveMsg = myAgent.receive(messageTemplate);
if (receiveMsg != null) {
String contenu = receiveMsg.getContent() + "(";
ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
if (noeud.getGauche() == null) {
message.setOntology(Constants.AFFICHAGE_VALUE);
message.addReceiver(myAgent.getAID());
} else {
message.setOntology(Constants.AFFICHAGE_VALUE_GAUCHE);
message.addReceiver(noeud.getGauche());
}
message.setContent(contenu);
myAgent.send(message);
} else {
block();
}
}
private void MessValue() {
MessageTemplate messageTemplate = MessageTemplate.and(
MessageTemplate.MatchOntology(Constants.AFFICHAGE_VALUE),
MessageTemplate.MatchPerformative(ACLMessage.REQUEST)
);
ACLMessage receiveMsg = myAgent.receive(messageTemplate);
if (receiveMsg != null) {
String contenu = receiveMsg.getContent() + (noeud.getValue() == null ? "" : noeud.getValue().toString());
ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
if (noeud.getDroit() == null){
message.setOntology(Constants.AFFICHAGE_VALUE_DROIT);
message.addReceiver(myAgent.getAID());
} else if (noeud.getDroit().equals(receiveMsg.getSender())){
message.setOntology(Constants.AFFICHAGE_VALUE_DROIT);
message.addReceiver(noeud.getPere());
} else {
message.setOntology(Constants.AFFICHAGE_VALUE_GAUCHE);
message.addReceiver(noeud.getDroit());
}
message.setContent(contenu);
myAgent.send(message);
} else {
block();
}
}
private void MessValueDroit() {
MessageTemplate messageTemplate = MessageTemplate.and(
MessageTemplate.MatchOntology(Constants.AFFICHAGE_VALUE_DROIT),
MessageTemplate.MatchPerformative(ACLMessage.REQUEST)
);
ACLMessage receiveMsg = myAgent.receive(messageTemplate);
if (receiveMsg != null) {
String contenu = receiveMsg.getContent() + ")";
ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
message.setContent(contenu);
if (noeud.getDroit() == null && noeud.getGauche() == null ){
if (noeud.getPere().equals(Constants.AID_RACINE)){
message.setPerformative(ACLMessage.CONFIRM);
} else {
message.setOntology(Constants.AFFICHAGE_VALUE_GAUCHE);
}
message.addReceiver(noeud.getPere());
}
myAgent.send(message);
} else {
block();
}
}
I don't know to fix the infini loop in my code. Who can help me the detailed algorithm instead the general? Or could fix my bug in code? Thank you!
A cyclicBehaviour is infinite by nature. Do not use a cyclic if you want the behaviour to stop.
Just use a simpleBehaviour and set the finished boolean at true when you want to remove it from the agent.
Related
I use it to check for null.DataSet has a structure of both String Integer and Bigdecimal data types.
How to shorten the condition code? Is there any way? To shorten my code. Thank you.
public void ConfrimData(DataSet data) {
if (StringUtils.isEmpty(data.getA())
|| StringUtils.isEmpty(data.getB())
|| StringUtils.isEmpty(data.getC())
|| StringUtils.isEmpty(data.getD())
|| StringUtils.isEmpty(data.getE())
|| StringUtils.isEmpty(data.getF())
){
if (StringUtils.isEmpty(data.getA())) {
loggerTransaction.info(Var.VALUE_A);
}
if (StringUtils.isEmpty(data.getB())) {
loggerTransaction.info(Var.VALUE_B);
}
if (StringUtils.isEmpty(data.getC())) {
loggerTransaction.info(Var.VALUE_C);
}
if (StringUtils.isEmpty(data.getD())) {
loggerTransaction.info(Var.VALUE_D);
}
if (StringUtils.isEmpty(data.getE())) {
loggerTransaction.info(Var.VALUE_E);
}
if (StringUtils.isEmpty(data.getF())) {
loggerTransaction.info(Var.VALUE_F);
}
return;
}
_DataSet
private String A = null;
private Integer B = null;
private String C= null;
private String D = null;
private BigDecimal E= null;
private String F= null;
Well, you could make it slightly less repeaty using streams, but it won't make it necessarily better, let alone faster:
LinkedHashMap<Supplier, String> map = new LinkedHashMap<>();
map.put(data::getA, Var.VALUE_A);
map.put(data::getB, Var.VALUE_B);
map.put(data::getC, Var.VALUE_C);
map.put(data::getD, Var.VALUE_D);
map.put(data::getE, Var.VALUE_E);
map.put(data::getF, Var.VALUE_F);
List<String> logMessages = map.entrySet().stream()
.filter(entry -> StringUtils.isEmpty(entry.getKey().get()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
if (!logMessages.isEmpty()) {
logMessages.forEach(loggerTransaction::info);
}
else {
// Remaining code
}
In your first if statement you check all the parameters to see if any of them are empty.
Then, in the inner if statements, you check them again. The first check is redundant. The return statement is also not necessary since it does not end the method early or returns any data.
Here is a shorter version that should give the same result:
public void confirmData(DataSet data) {
if (StringUtils.isEmpty(data.getA())) {
loggerTransaction.info(Var.VALUE_A);
}
if (StringUtils.isEmpty(data.getB())) {
loggerTransaction.info(Var.VALUE_B);
}
if (StringUtils.isEmpty(data.getC())) {
loggerTransaction.info(Var.VALUE_C);
}
if (StringUtils.isEmpty(data.getD())) {
loggerTransaction.info(Var.VALUE_D);
}
if (StringUtils.isEmpty(data.getE())) {
loggerTransaction.info(Var.VALUE_E);
}
if (StringUtils.isEmpty(data.getF())) {
loggerTransaction.info(Var.VALUE_F);
}
}
EDIT
Here is a slightly prettier solution with less code repetition:
public void confirmData(DataSet data) {
logIfEmpty(data.getA(), Var.VALUE_A);
logIfEmpty(data.getB(), Var.VALUE_B);
logIfEmpty(data.getC(), Var.VALUE_C);
logIfEmpty(data.getD(), Var.VALUE_D);
logIfEmpty(data.getE(), Var.VALUE_E);
logIfEmpty(data.getF(), Var.VALUE_F);
}
private void logIfEmpty(Object check, String log) {
if (StringUtils.isEmpty(check)) {
loggerTransaction.info(log);
}
}
EDIT #2
And if you have other code you want to execute if you did not find any empty values, you can do this:
public void confirmData(DataSet data) {
boolean foundEmpty;
foundEmpty = logIfEmpty(data.getA(), Var.VALUE_A);
foundEmpty = logIfEmpty(data.getB(), Var.VALUE_B) || foundEmpty;
foundEmpty = logIfEmpty(data.getC(), Var.VALUE_C) || foundEmpty;
foundEmpty = logIfEmpty(data.getD(), Var.VALUE_D) || foundEmpty;
foundEmpty = logIfEmpty(data.getE(), Var.VALUE_E) || foundEmpty;
foundEmpty = logIfEmpty(data.getF(), Var.VALUE_F) || foundEmpty;
if(foundEmpty) {
return;
}
}
private boolean logIfEmpty(String check, String log) {
if (StringUtils.isEmpty(check)) {
loggerTransaction.info(log);
return true;
}
return false;
}
Maybe assigning a flag...
public void ConfrimData(DataSet data) {
boolean flag;
if (flag = StringUtils.isEmpty(data.getA())) {
loggerTransaction.info(Var.VALUE_A);
}
if (flag = StringUtils.isEmpty(data.getB()) || flag) {
loggerTransaction.info(Var.VALUE_B);
}
if (flag = StringUtils.isEmpty(data.getC()) || flag) {
loggerTransaction.info(Var.VALUE_C);
}
if (flag = StringUtils.isEmpty(data.getD()) || flag) {
loggerTransaction.info(Var.VALUE_D);
}
if (flag = StringUtils.isEmpty(data.getE()) || flag) {
loggerTransaction.info(Var.VALUE_E);
}
if (flag = StringUtils.isEmpty(data.getF()) || flag) {
loggerTransaction.info(Var.VALUE_F);
}
if (flag) return;
I'm using an embedded Neo4j instance in my Spring Boot project (I'm using Spring JPA and Neo4j separately and I'm not using Spring-Boot-Neo4j stuff) and I want to visualise the graph I build using the Neo4j browser that I downloaded from here with the addition of a custom init.coffee that allows it to display images inside the nodes
This is the code I use in order to build my graph. The "buildGraph" function is executed when a request is being received by one of my RestControllers
(the reason I include all of my business logic implementation is because it may help detecting relationships/nodes etc being created/handled in a wrong way)
#Component
public class GraphBuilder
{
private String dbPath;
private int numberOFConnectionsForKeyIndividuals;
private String neo4jBoltAddress;
#Autowired
PersonService personService;
private final GraphDatabaseService graphDb;
public GraphBuilder(#Value("${dbPath}") String dbPath,
#Value("${neo4jBoltAddress}") String neo4jBoltAddress,
#Value("${numberOFConnectionsForKeyIndividuals}") int numberOFConnectionsForKeyIndividuals)
{
GraphDatabaseSettings.BoltConnector bolt = GraphDatabaseSettings.boltConnector( "0" );
this.dbPath = dbPath;
this.neo4jBoltAddress = neo4jBoltAddress;
this.numberOFConnectionsForKeyIndividuals = numberOFConnectionsForKeyIndividuals;
graphDb = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder( new File(dbPath) )
.setConfig( bolt.type, "BOLT" )
.setConfig( bolt.enabled, "true" )
.setConfig( bolt.address, neo4jBoltAddress )
.newGraphDatabase();
registerShutdownHook( graphDb );
}
public void buildGraph()
{
List<Long> AsIDs = new ArrayList<>();
Map<Long,Long> personIdToNodeMap = new HashMap<>();
Map<String,List<Long>> nameToId = new HashMap<>();
Map<Long,List<Association>> associationsMap = new HashMap<>();
try ( Transaction tx = graphDb.beginTx() )
{
Schema schema = graphDb.schema();
for(Person person : personService.findAllPersons())
{
Node personNode = graphDb.createNode(new Label() {
#Override
public String name() {
return "Person";
}
});
//mapping persons to their respective nodes
personIdToNodeMap.put(person.getPersonId(),personNode.getId());
//mapping names to the ids of the persons
if(nameToId.get(person.getName()) == null)
{
nameToId.put(person.getName(), new ArrayList<>());
}
nameToId.get(person.getName()).add(person.getPersonId());
personNode.setProperty("Name", person.getName());
for(int a = 0 ; a < person.getAliases().size() ; a++)
{
personNode.setProperty("Alias " + a+1, person.getAliases().get(a).getAlias());
}
personNode.setProperty("Additional Name Information", person.getAdditionalNameInformation() != null ? person.getAdditionalNameInformation() : "");
personNode.setProperty("Id", person.getPersonId());
personNode.setProperty("Date of Birth", person.getDob() != null ? person.getDob() : "");
for(int f = 0 ; f < person.getFacebook().size() ; f++)
{
personNode.setProperty("Facebook " + f+1, person.getFacebook().get(f).getFacebookPage() + " (" + person.getFacebook().get(f).getAdditionalFacebookPageInformation() + ")");
}
personNode.setProperty("Additional Information", person.getInfo() != null ? person.getInfo() : "");
personNode.setProperty("image_url","http://localhost:8888/files/"+person.getPictureFilePath());
personNode.setProperty("Node Type", "Person");
if(person.getAssociations().size() > numberOFConnectionsForKeyIndividuals)
{
personNode.setProperty("Key_Individual","Yes");
}
for(A A : person.getAs())
{
Node ANode = graphDb.createNode(new Label() {
#Override
public String name() {
return "A";
}
});
ANode.setProperty("A", A.getA());
//TODO elaborate more on the A with additional properties
ANode.setProperty("Node Type", "A");
personNode.createRelationshipTo( ANode, EdgeTypes.HAS_DONE );
ANode.setProperty("image_url","http://localhost:8888/images/A.png");
AsIDs.add(ANode.getId());
}
for(Association association : person.getAssociations())
{
if(associationsMap.get(person.getPersonId()) == null)
{
associationsMap.put(person.getPersonId(), new ArrayList<>());
}
associationsMap.get(person.getPersonId()).add(association);
}
}
//Validating and building the association edges
//iterating through the nodes
for(Long personFromId : associationsMap.keySet())
{
//iterating through the associations registered for the node
for(Association associationFrom : associationsMap.get(personFromId))
{
String personNameFrom = associationFrom.getPersonNameFrom();
String personNameTo = associationFrom.getPersonNameTo();
//iterating through the persons whose name matches the other end of the association
if(nameToId.get(personNameTo) != null)
{
for(Long personToId : nameToId.get(personNameTo))
{
//iterating through the associations of the person at the other end of the association
if(associationsMap.get(personToId) != null)
{
List<Association> associationsToRemove = new ArrayList<>();
for(Association associationTo : associationsMap.get(personToId))
{
if(associationTo.getPersonNameTo().equals(personNameFrom) && nameToId.get(personNameFrom).contains(personFromId))
{
if(nameToId.get(personNameFrom).size() == 1)
{
Relationship relationship = graphDb.getNodeById(personIdToNodeMap.get(personFromId))
.createRelationshipTo( graphDb.getNodeById(personIdToNodeMap.get(personToId)), EdgeTypes.ASSOCIATES_WITH );
if(associationFrom.getType() != null)
{
relationship.setProperty("Association Type",associationFrom.getType());
}
associationsToRemove.add(associationTo);
}
else
{
boolean alreadyConnected = false;
for(Relationship rel : graphDb.getNodeById(personIdToNodeMap.get(personFromId)).getRelationships())
{
if( ( rel.getOtherNode(graphDb.getNodeById(personIdToNodeMap.get(personFromId))).
equals(graphDb.getNodeById(personIdToNodeMap.get(personToId))) ) )
{
alreadyConnected = true;
break;
}
}
if(!alreadyConnected)
{
Relationship relationship = graphDb.getNodeById(personIdToNodeMap.get(personFromId))
.createRelationshipTo( graphDb.getNodeById(personIdToNodeMap.get(personToId)), EdgeTypes.PROBABLY_ASSOCIATES_WITH );
if(associationFrom.getType() != null)
{
relationship.setProperty("Association Type",associationFrom.getType());
}
}
// associationsToRemove.add(associationTo);
}
}
}
associationsMap.get(personToId).removeAll(associationsToRemove);
}
}
}
}
}
tx.success();
}
Map<Long,List<String>> AToNamesMap = new HashMap<>();
//detecting names referred in the A's description
try(Transaction txAs = graphDb.beginTx() )
{
for(Long id : AsIDs)
{
Node ANode = graphDb.getNodeById(id);
String A = (String) ANode.getProperty("A");
for(String name : nameToId.keySet())
{
if(A.contains(name)) {
if(AToNamesMap.get(id) == null)
{
AToNamesMap.put(id,new ArrayList<>());
}
AToNamesMap.get(id).add(name);
}
}
}
List<Long> groupedAs = new ArrayList<>();
for(Long id : AsIDs)
{
if(AToNamesMap.get(id)!= null && AToNamesMap.get(id).size() > 1)
{
for(Long otherAID : AToNamesMap.keySet())
{
if(id != otherAID && !groupedAs.contains(otherAID) && !groupedAs.contains(id))
{
if(compareNamesLists(AToNamesMap.get(id), AToNamesMap.get(otherAID)))
{
Relationship rel = graphDb.getNodeById(otherAID).getSingleRelationship(EdgeTypes.HAS_DONE,Direction.INCOMING);
Node otherPersonNode = rel.getStartNode();
if(nameToId.get(otherPersonNode.getProperty("Name")) != null && nameToId.get(otherPersonNode.getProperty("Name")).size() > 1)
{
otherPersonNode.createRelationshipTo(graphDb.getNodeById(id), EdgeTypes.HAS_PROBABLY_DONE);
}
else
{
otherPersonNode.createRelationshipTo(graphDb.getNodeById(id), EdgeTypes.HAD_DONE);
}
rel.delete();
graphDb.getNodeById(otherAID).delete();
groupedAs.add(otherAID);
}
}
}
}
groupedAs.add(id);
}
txAs.success();
}
}
private static void registerShutdownHook( final GraphDatabaseService graphDb )
{
// Registers a shutdown hook for the Neo4j instance so that it
// shuts down nicely when the VM exits (even if you "Ctrl-C" the
// running application).
Runtime.getRuntime().addShutdownHook( new Thread()
{
#Override
public void run()
{
graphDb.shutdown();
}
} );
}
}
When I open the browser and connect it to the bolt that I expose for my embedded neo4j, the browser is able to show all the nodes in my graph database (at the moment less than 100) and it then freezes, causing the entire system to freeze (MacBook Pro 2016, 16GB). This happens around 3/5 times.
I know that the way I make my transactions is not ideal, but as I said all this processing happens before the neo4j browser starts.
Can you advise me on how to solve this issue?
Can you see anything in my code (connection left open etc) Is this a known issue for the neo4j browser?
The default implementation of ASTVisitor traverses in a depth first manner. So one can get the source file in order of occurrence. My requirement is to build a java tree out of the ASTNode
I am motivated by the following
API to compare AST?
http://www.programcreek.com/2011/11/use-jdt-astparser-to-parse-java-file/
Eclipse Abstract Syntax Tree Diff
public class AST_Json_Bulid_tree
{
static private List sourcecodeStatObj = new LinkedList();
public static void parse(String str, final String path)
{
ASTParser parser = ASTParser.newParser(AST.JLS8 );
parser.setSource(str.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setResolveBindings(true); // we need bindings later on
final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
try{
cu.accept(new ASTVisitor()
{
public boolean visit(ForStatement node)
{
List<String> initializer = node.initializers();
Expression exp = node.getExpression();
String expression = "";
List updater = node.updaters();
int length = node.getBody().getLength();
int startposition = node.getStartPosition();
int startLineNumber = cu.getLineNumber(node.getStartPosition());
int nodeLength = node.getLength();
int endLineNumber = cu.getLineNumber(node.getStartPosition() + nodeLength);
boolean isexpNull = false ;
forcount += 1;
if(exp == null)
{
isexpNull = true;
}
if(!isexpNull)
{
this.names.add(exp.toString());
expression = exp.toString();
}
Map forobj=new LinkedHashMap();
forobj.put("Node_Type", "FOR_STATEMENT");
forobj.put("keyword", "for");
forobj.put("Initializers", initializer.toString());
forobj.put("Expression", expression);
forobj.put("Updater", updater.toString());
forobj.put("CF.BeginLine, CF.EndLine", "(" + startLineNumber + ", " + endLineNumber + ")");
String astjsonText = JSONValue.toJSONString(forobj);
try
{
sourcecodeStatObj.add(forobj);
}
catch (Exception e)
{
e.printStackTrace();
}
//Accept the visit of the other parts
//super.visit(node);
if(!isexpNull)
{
exp.accept(this);
}
for (Iterator it = node.initializers().iterator(); it.hasNext(); )
{
Expression e = (Expression) it.next();
e.accept(this);
}
for (Iterator it = node.updaters().iterator(); it.hasNext(); )
{
Expression e = (Expression) it.next();
e.accept(this);
}
node.getBody().accept(this);
return false; // continue
}
public boolean visit(WhileStatement node)
{
// Similar code goes here
return false; // don't continue to visit
}
public boolean visit(DoStatement node)
{
// Similar code goes here
return false; // don't continue to visit
}
public boolean visit (IfStatement node)
{
// Similar code goes here
return false; // don't continue to visit
}
public boolean visit(MethodDeclaration node)
{
// Similar code goes here
return false;
}
public boolean visit(TypeDeclaration node)
{
// Similar code goes here
return true;
}
public boolean visit(AnnotationTypeDeclaration node)
{
// Similar code goes here
return true;
}
public boolean visit(PackageDeclaration node)
{
// Similar code goes here
return false;
}
public boolean visit(EnumDeclaration node)
{
// Similar code goes here
return true;
}
#SuppressWarnings("static-access")
public boolean visit(Block node)
{
// Similar code goes here
return true;
}
public boolean visit(ImportDeclaration node)
{
// Similar code goes here
return false;
}
//Other STATEMENTs goes here
});
}
finally
{
writeJsonFile(path);
}
}
}
So here the sourcecodeStatObj contains all the items in order of visited i.e depth first search.
other class's and methods' constructs are omitted here.
I would appreciate if you give me the direction and the twist!
Thank you!
private Object artikanID(String string) {
try {
DAOTerjemah dao = new DAOTerjemah(ConnectionDB.getConnection()) {};
List<Kata> terjemahan1 = new ArrayList<Kata>();
List<Kata> terjemahan2 = new ArrayList<Kata>();
List<Kata> terjemahan3 = new ArrayList<Kata>();
terjemahan1 = dao.getByIndo(string);
terjemahan2 = dao.getByIndo(string.substring(0,string.length()-1));
terjemahan3 = dao.getByIndo(string.substring(0,string.length()-2));
if (terjemahan1 == null) {
return terjemahan1.get(0).getDayak();
}
else {
return terjemahan2.get(0).getDayak();
}
}catch(Exception e){
return string ;
}
}
there are 3 conditions(terjemahan1,terjemahan2 & terjemahan 3),
how to create the conditions to be executed terjemahan3 ?
With an else, but I'm not entirely sure I understand your logic.
if (terjemahan1 == null) {
return terjemahan1.get(0).getDayak();
}
else if (terjemahan2 == null) {
return terjemahan2.get(0).getDayak();
}
else {
return terjemahan3.get(0).getDayak();
}
I think you probably want the opposite though, so you only call this on variables that are not null. In this case you have to decide which one you want to call in preference if they are all not null. Also you have to decide what to do if all of them are null.
if (terjemahan1 != null) {
return terjemahan1.get(0).getDayak();
}
else if (terjemahan2 != null) {
return terjemahan2.get(0).getDayak();
}
else if (terjemahan3 != null) {
return terjemahan3.get(0).getDayak();
}
else
{
// decide what to do in this condition
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I was asked to work on this back-end scheduled job that export some customers data (from an e-commerce DB) to a custom-format text file. The code that follows is what I found.
I just would like to delete it all, but I can't. Would it be possible for me to improve this without changing it so much?
public class AConverter implements CustomerConverter {
protected final Logger LOG = LoggerFactory.getLogger(AConverter.class);
private final static String SEPARATOR = ";";
private final static String CR = "\n";
public String create(Customer customer) {
if (customer == null)
return null;
LOG.info("Exporting customer, uidpk: {}, userid: {}", customer.getUidPk(), customer.getUserId());
StringBuilder buf = new StringBuilder();
buf.append("<HEAD>");
buf.append(SEPARATOR);
buf.append(String.valueOf(customer.getUidPk()));
buf.append(SEPARATOR);
byte[] fullName = null;
try {
fullName = customer.getFullName().getBytes("UTF-8");
} catch (UnsupportedEncodingException e1) {
fullName = customer.getFullName().getBytes();
}
String name = null;
try {
name = new String(fullName, "UTF-8");
} catch (UnsupportedEncodingException e) {
name = customer.getFullName();
}
buf.append(limitString(name, 40));
buf.append(SEPARATOR);
final CustomerAddress preferredShippingAddress = customer.getPreferredShippingAddress();
if (preferredShippingAddress != null) {
final String street1 = preferredShippingAddress.getStreet1();
if (street1 != null) {
buf.append(limitString(street1, 40));
}
} else {
buf.append(" ");
}
buf.append(SEPARATOR);
final String addressStr = buildAddressString(customer);
buf.append(limitString(addressStr, 40));
buf.append(SEPARATOR);
buf.append(limitString(customer.getEmail(), 80));
buf.append(SEPARATOR);
if (preferredShippingAddress!=null && preferredShippingAddress.getStreet2() != null) {
buf.append(limitString(preferredShippingAddress.getStreet2(), 40));
} else {
buf.append(" ");
}
buf.append(SEPARATOR);
buf.append(limitString(customer.getPhoneNumber(), 25));
buf.append(SEPARATOR);
if (preferredShippingAddress!=null) {
if(preferredShippingAddress.getCountry()!=null) {
buf.append(preferredShippingAddress.getCountry());
} else {
buf.append(" ");
}
} else {
buf.append(" ");
}
buf.append(SEPARATOR);
if (preferredShippingAddress!=null) {
if(preferredShippingAddress.getCountry()!=null) {
buf.append(preferredShippingAddress.getCountry());
} else {
buf.append(" ");
}
} else {
buf.append(" ");
}
buf.append(SEPARATOR);
String fodselsnummer = " ";
try {
Map<String, AttributeValue> profileValueMap = customer.getProfileValueMap();
AttributeValue attributeValue = profileValueMap.get("CODE");
fodselsnummer = attributeValue.getStringValue();
} catch (Exception e) {
}
buf.append(fodselsnummer);
buf.append(CR);
final String string = buf.toString();
return string;
}
private String buildAddressString(Customer customer) {
final CustomerAddress preferredShippingAddress = customer.getPreferredShippingAddress();
if (preferredShippingAddress != null) {
final String zipOrPostalCode = preferredShippingAddress.getZipOrPostalCode();
final String city = preferredShippingAddress.getCity();
if (zipOrPostalCode != null && city != null) {
return zipOrPostalCode + " " + city;
} else if(zipOrPostalCode == null && city != null) {
return city;
} else if(zipOrPostalCode != null && city == null) {
return zipOrPostalCode;
}
}
return " ";
}
private String limitString(String value, int numOfChars) {
if (value != null && value.length() > numOfChars)
return value.substring(0, numOfChars);
else
return value;
}
}
You say you want to improve it, you'd like to delete it, but you can't. I'm not sure why you can't. I also don't understand why you'd want to delete it. But it sounds to me like the kind of attitude I used to have before I read Refactoring by Martin Fowler. I would strongly suggest you read that book, if you haven't already.
It is certainly possible to improve this code (or any code) without rewriting it all. The most obvious improvements would be to eliminate some of the repetitive code in the create method by creating some utility methods, and then breaking up the create method into several smaller methods à la template methods.
Also, there is a questionable bit of code in the create method that turns the customer's name into a UTF-8 byte stream and then back into a string. I can't imagine what that's for. Finally, it returns null if the customer is null. That is unlikely to be necessary or wise.
For fun, I decided to do a little refactoring on this code. (Note that proper refactoring involves unit tests; I don't have any tests for this code and have not even compiled the code below, much less tested it.) Here is one possible way you could rewrite this code:
public class AConverter implements CustomerConverter {
protected final Logger LOG = LoggerFactory.getLogger(AConverter.class);
private final static String SEPARATOR = ";";
private final static String CR = "\n";
public String create(Customer customer) {
if (customer == null) throw new IllegalArgumentException("no cust");
LOG.info("Exporting customer, uidpk: {}, userid: {}",
customer.getUidPk(), customer.getUserId());
StringBuilder buf = new StringBuilder();
doHead(buf, customer);
doAddress(buf, customer);
doTail(buf, customer);
return buf.toString();
}
private void doHead(StringBuilder buf, Customer customer) {
append(buf, "<HEAD>");
append(buf, String.valueOf(customer.getUidPk()));
append(buf, limitTo(40, customer.getFullName()));
}
private void doAddress(StringBuilder buf, Customer customer) {
append(buf, limitTo(40, street1of(customer)));
append(buf, limitTo(40, addressOf(customer)));
append(buf, limitTo(80, customer.getEmail()));
append(buf, limitTo(40, street2of(customer)));
append(buf, limitTo(25, customer.getPhoneNumber()));
append(buf, countryOf(customer));
append(buf, countryOf(customer));
}
private void doTail(StringBuilder buf, Customer customer) {
buf.append(fodselsnummerOf(customer));
buf.append(CR);
}
private void append(StringBuilder buf, String s) {
buf.append(s).append(SEPARATOR);
}
private String street1of(Customer customer) {
final CustomerAddress shipto = customer.getPreferredShippingAddress();
if (shipto == null) return " ";
if (shipto.getStreet1() != null) return shipto.getStreet1();
return " ";
}
private String street2of(Customer customer) {
final CustomerAddress shipto = customer.getPreferredShippingAddress();
if (shipto == null) return " ";
if (shipto.getStreet2() != null) return shipto.getStreet2();
return " ";
}
private String addressOf(Customer customer) {
final CustomerAddress shipto = customer.getPreferredShippingAddress();
if (shipto == null) return " ";
final String post = preferredShippingAddress.getZipOrPostalCode();
final String city = preferredShippingAddress.getCity();
if (post != null && city != null) return post + " " + city;
if (post == null && city != null) return city;
if (post != null && city == null) return post;
return " ";
}
private String countryOf(Customer customer) {
final CustomerAddress shipto = customer.getPreferredShippingAddress();
if (shipto == null) return " ";
if (shipto.getCountry() != null) return shipto.getCountry();
return " ";
}
private String limitTo(int numOfChars, String value) {
if (value != null && value.length() > numOfChars)
return value.substring(0, numOfChars);
return value;
}
private String fodelsnummerOf(Customer customer) {
try {
Map<String, AttributeValue> profileValueMap =
customer.getProfileValueMap();
AttributeValue attributeValue = profileValueMap.get("CODE");
return attributeValue.getStringValue();
} catch (Exception e) {
return " ";
}
}
}
I also notice that there is a problem with your format for the custom-format text file if any of the fields of the customer data (email address, for example) happen to have a semicolon in them, because that is your separator character. I trust that is a known issue?