I'm learning the Builder Pattern. I have a question, Why don't using a class (ex: MyCoffe)instead of 2 class (ex: MyCoffe, BuilderClass). Thanks you for reading.
package Creational.Builder;
public class MyCoffe {
private String name;
private int id;
public MyCoffe(){
}
public MyCoffe setName(String newName){
this.name = newName;
return this;
}
public MyCoffe setId(int newId){
this.id = newId;
return this;
}
public MyCoffe build(){
return this;
}
public String toString(){
return name + "/" + id;
}
public static void main(String[] args){
MyCoffe myCoffe = new MyCoffe().setName("HelloWorld").setId(9999);
System.out.println(myCoffe);
System.out.println("Thanks for help!");
}
}
You certainly can in some select situations, but one of the purposes of the builder pattern is to avoid having an invalid instance of a class. So unless it's valid for MyCoffe to not have a name or ID, you don't want an instance of it running around without a name or ID, like this:
MyCoffe invalid = new MyCoffe();
Also note that when the class is self-building like that, it's easy to forget to call the final build method (as, in fact, you did in your main), so the instance never gets validated.
Hence using a separate builder to hold the incomplete information before building the complete, valid instance.
In Java, it's not uncommon for the builder to be a static nested class:
public class MyCoffe {
public static class Builder {
private String name;
private int id;
public Builder() {
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setId(int id) {
this.id = id;
return this;
}
public MyCoffe build() {
if (this.name == null) {
throw new AppropriateException("'name' is required");
}
if (this.id == 0) { // Assumes 0 isn't a valid ID
throw new AppropriateException("'id' is required");
}
return new MyCoffe(name, id);
}
}
private String name;
private int id;
public MyCoffe(String name, int id) {
this.name = name;
this.id = id;
}
#Override
public String toString(){
return name + "/" + id;
}
public static void main(String[] args){
MyCoffe myCoffe = new MyCoffe.Builder().setName("HelloWorld").setId(9999).build();
System.out.println(myCoffe);
System.out.println("Thanks for help!");
}
}
Or if declaring the properties twice like that bothers you, MyCoffe can allow private incomplete instances, like this:
public class MyCoffe {
public static class Builder {
private MyCoffe instance;
public Builder() {
this.instance = new MyCoffe();
}
public Builder setName(String name) {
this.instance.name = name;
return this;
}
public Builder setId(int id) {
this.instance.id = id;
return this;
}
public MyCoffe build() {
if (this.instance.name == null) {
throw new AppropriateException("'name' is required");
}
if (this.instance.id == 0) { // Assumes 0 isn't a valid ID
throw new AppropriateException("'id' is required");
}
return this.instance;
}
}
private String name;
private int id;
private MyCoffe() {
}
public MyCoffe(String name, int id) {
this.name = name;
this.id = id;
}
#Override
public String toString(){
return name + "/" + id;
}
public static void main(String[] args){
MyCoffe myCoffe = new MyCoffe.Builder().setName("HelloWorld").setId(9999).build();
System.out.println(myCoffe);
System.out.println("Thanks for help!");
}
}
Related
Currently I'm trying to Hardcode some values for a family tree application in Java.
Just need some ideas on how to go about it, not sure how to proceed.
I have also included the constructor classes:
public class TreeImpl {
private FamilyMember root;
public FamilyMember getRoot() {
return root;
}
public void setRoot(FamilyMember root) {
this.root = root;
}
public List<FamilyMember> getAllMembers() {
return allMembers;
}
public void setAllMembers(List<FamilyMember> allMembers) {
this.allMembers = allMembers;
this.setRoot(this.allMembers.get(0));
}
private List<FamilyMember> allMembers = new ArrayList<>();
public TreeImpl(FamilyMember root)
{
this.root=root;
addMembers(root);
}
private void addMembers(FamilyMember node)
{
if(node==null) return;
allMembers.add(node);
addMembers(node.getFather());
addMembers(node.getMother());
addMembers(node.getSpouse());
for(FamilyMember child : node.getChildren())
addMembers(child);
}
public void addSpouse(int index, FamilyMember spouse)
{
for(FamilyMember member : allMembers)
{
if(member.getMemberID()==index)
{
member.setSpouse(spouse);
allMembers.add(spouse);
return;
}
}
}
public void addFather(int index, FamilyMember father)
{
for(FamilyMember member : allMembers)
{
if(member.getMemberID()==index)
{
member.setFather(father);
allMembers.add(father);
return;
}
}
}
public void addMother(int index, FamilyMember mother)
{
for(FamilyMember member : allMembers)
{
if(member.getMemberID()==index)
{
member.setMother(mother);
allMembers.add(mother);
return;
}
}
}
public void addChild(int index, FamilyMember child)
{
for(FamilyMember member : allMembers)
{
if(member.getMemberID()==index)
{
member.setSpouse(child);
allMembers.add(child);
return;
}
}
}
public FamilyMember getDetailsForMember(String member)
{
for(FamilyMember m : this.getAllMembers())
{
if(m.getFirstName().equals(member))
return m;
}
return null;
}
My constructor class
public class FamilyMember implements Serializable{
private static int id=1;
private String firstName, surName, surNameAfterMarriage, life;
private Gender gender;
private Address address;
private FamilyMember mother, father, spouse;
private int memberID;
public boolean hasSub()
{
return (this.getFather()!=null || this.getMother()!=null || this.getChildren().size()>0);
}
public int getMemberID() {
return memberID;
}
public void setMemberID(int memberID) {
this.memberID = memberID;
}
private List<FamilyMember> children, grandChildren;
public static int getId() {
return id;
}
public static void incrementId()
{
id++;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurName() {
return surName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public String getSurNameAfterMarriage() {
return surNameAfterMarriage;
}
public void setSurNameAfterMarriage(String surNameAfterMarriage) {
this.surNameAfterMarriage = surNameAfterMarriage;
}
public String getLife() {
return life;
}
public void setLife(String life) {
this.life = life;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public FamilyMember getMother() {
return mother;
}
public void setMother(FamilyMember mother) {
this.mother = mother;
}
public FamilyMember getFather() {
return father;
}
public void setFather(FamilyMember father) {
this.father = father;
}
public FamilyMember(String firstName, String surName, String surNameAfterMarriage, String life, Gender gender,
Address address) {
super();
this.firstName = firstName;
this.surName = surName;
this.surNameAfterMarriage = surNameAfterMarriage;
this.life = life;
this.gender = gender;
this.address = address;
this.memberID = this.getId();
this.children = new ArrayList<>();
this.incrementId();
}
for(FamilyMember child : this.getChildren())
{
text = text + " " + child.firstName;
}
return text;
}
public FamilyMember getSpouse() {
return spouse;
}
public void setSpouse(FamilyMember spouse) {
this.spouse = spouse;
}
public List<FamilyMember> getChildren() {
return children;
}
public void setChildren(List<FamilyMember> childer) {
this.children = childer;
}
public void addChild(FamilyMember child) {
this.children.add(child);
}
public List<FamilyMember> getGrandChildren() {
return grandChildren;
}
public void setGrandChildren(List<FamilyMember> grandChildren) {
this.grandChildren = grandChildren;
}
}
For examples, I want to add details for father, mothers, child etc so when I run the program, these values are displayed
Eg: Familymember father = new Familymember ("xyz". "xyx" )
You can set values using Constructor,
public FamilyMember (Gender gen,Address add,FamilyMember fmm,FamilyMember fmf,FamilyMember fms,int mId){
this.gender = gen;
this.address = add;
this.mother = fmm;
this.father = fmf;
this.spouse = fms;
this.memberID = mId;
}
it will set the FamilyMember object with hard coded values,
FamilyMember fm = new FamilyMember(Gender.MALE,add,fmm,fmf,fms,menId);
Let me know if any quires.
If you really want it through a constructor, you could do it this way:
// Secondary constructor
public FamilyMember() {
this("Paul", "Stevenson", ...); // calls the primary constructor
}
public FamilyMember(String firstName, String surName, String surNameAfterMarriage, String life, Gender gender,
Address address) {
// your primary constructor
}
Unfortunately this isn't very flexible. An alternative is to use a static method :
public static FamilyMember familyMemberSteve() {
return new FamilyMember("Steve", ...)
}
But to be honest, I wouldn't recommend this either. Like I said in the comment, it would be better to use XML or another format, because it would be more flexible.
Create a a static method in FamilyMember class that creates a family and then call this method before initialising a TreeImpl object.
public static FamilyMember createFirstFamilyNode() {
FamilyMember mother = new FamilyMember("Mother", ...);
FamilyMember father = new FamilyMember("Father", ...);
mother.setSpouce(father);
FamilyMember child1 = new FamilyMember("First Child", ...);
mother.addChild(child1);
// And so on for rest of family members
return mother;
}
I am just creating a handler in java which accepts a POJO called as ProductsModel.
public ProductsResponseObject handleRequest(ProductsRequestObject productsRequestObject, Context arg1) {
ProductsResponseObject respObj = null;
ProductsService productsService = new ProductsService();
arg1.getLogger().log("inside ProductsHandler.handleRequest with reqtype " + productsRequestObject.getReqType());
switch (productsRequestObject.getReqType()) {
case 0:
respObj = productsService.addProduct(productsRequestObject);
break;
case 1:
respObj = productsService.updateProduct(productsRequestObject);
break;
default:
break;
}
return respObj;
}
But here inside the handler method, the attributes of request, reqType and productModel are null. Not sure y?
Request POJO:
public class ProductsRequestObject {
private int reqType;
private ProductsModel productsModel;
public int getReqType() {
return reqType;
}
public void setReqType(int reqType) {
this.reqType = reqType;
}
public ProductsModel getProductsModel() {
return productsModel;
}
public void setProductsModel(ProductsModel productsModel) {
this.productsModel = productsModel;
}
}
Model POJO:
public class ProductsModel {
private String id;
private String dealerMobNumber;
private String name;
private String description;
private String price;
#DynamoDBHashKey(attributeName = "Id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDealerMobNumber() {
return dealerMobNumber;
}
public void setDealerMobNumber(String dealerMobNumber) {
this.dealerMobNumber = dealerMobNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
I've developed two sets of classes - the first one are just classes, whereas in the second set, the classes derive from interfaces. Both the sets of classes mimic each other. The repositories for them are also similar. However, the repository works well for the first set of classes (nodes and relationships). For the second set of classes though, the repository is able to insert records, but the findAll method fails and doesn't return me any records.
Here's the first set of classes with the repository -
public abstract class Entity {
#GraphId
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || id == null || getClass() != o.getClass()) return false;
Entity entity = (Entity) o;
if (!id.equals(entity.id)) return false;
return true;
}
#Override
public int hashCode() {
return (id == null) ? -1 : id.hashCode();
}
}
public abstract class GenericRepository<T> implements IGenericRepository<T> {
private static final int DEPTH_LIST = 1;
private static final int DEPTH_ENTITY = 2;
private Session session;
public GenericRepository(String url, String username, String password) {
super();
session = Neo4jSessionFactory.getInstance().getNeo4jSession(url, username, password);
}
public Iterable<T> findAll() {
return session.loadAll(getEntityType(), DEPTH_LIST);
}
public T findOne(Long id) {
return session.load(getEntityType(), id, DEPTH_ENTITY);
}
public void delete(T entity) {
session.delete(session.load(getEntityType(), ((Entity) entity).getId()));
}
public T createOrUpdate(T entity) {
session.save(entity, DEPTH_ENTITY);
return findOne(((Entity) entity).getId());
}
public abstract Class<T> getEntityType();
}
#RelationshipEntity(type="MY_ROLE")
public class ARole extends Entity {
#Property
private String title;
#StartNode
private HomoSapiens start;
#EndNode
private HomoSapiens end;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public HomoSapiens getStart() {
return start;
}
public void setStart(HomoSapiens start) {
this.start = start;
}
public HomoSapiens getEnd() {
return end;
}
public void setEnd(HomoSapiens end) {
this.end = end;
}
public ARole() {}
public ARole(String title) {
this.title = title;
}
}
#NodeEntity
public class HomoSapiens extends Entity {
private String name;
#Relationship(type = "MY_ROLE", direction = Relationship.INCOMING)
private ARole aRole;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ARole getaRole() {
return aRole;
}
public void setaRole(ARole aRole) {
this.aRole = aRole;
}
public HomoSapiens() {}
public HomoSapiens(String name) {
this.name = name;
}
}
public class ARoleDao extends GenericRepository<ARole> implements IARoleDao {
public ARoleDao(String url, String username, String password) {
super(url, username, password);
}
#Override
public Class<ARole> getEntityType() {
return ARole.class;
}
}
Here's the second set of classes -
public interface IARole {
String getTitle();
void setTitle(String title);
IHomoSapiens getStart();
void setStart(IHomoSapiens start);
IHomoSapiens getEnd();
void setEnd(IHomoSapiens end);
}
public interface IHomoSapiens {
String getName();
void setName(String name);
IARole getARole();
void setARole(IARole aRole);
}
#RelationshipEntity(type="MY_DERIVED_ROLE")
public class DerivedARole extends Entity implements IARole {
#Property
private String title;
#StartNode
private IHomoSapiens start;
#EndNode
private IHomoSapiens end;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public IHomoSapiens getStart() {
return start;
}
public void setStart(IHomoSapiens start) {
this.start = start;
}
public IHomoSapiens getEnd() {
return end;
}
public void setEnd(IHomoSapiens end) {
this.end = end;
}
public DerivedARole() {}
public DerivedARole(String title) {
this.title = title;
}
}
#NodeEntity
public class DerivedHomoSapiens extends Entity implements IHomoSapiens {
private String name;
#Relationship(type = "MY_DERIVED_ROLE", direction = Relationship.INCOMING)
private IARole aRole;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IARole getARole() {
return aRole;
}
public void setARole(IARole aRole) {
this.aRole = aRole;
}
public DerivedHomoSapiens() {}
public DerivedHomoSapiens(String name) {
this.name = name;
}
}
public class DerivedARoleDao extends GenericRepository<DerivedARole> {
public DerivedARoleDao(String url, String username, String password) {
super(url, username, password);
}
#Override
public Class<DerivedARole> getEntityType() {
return DerivedARole.class;
}
}
public class DerivedARoleDaoSpecs {
private DerivedARoleDao derivedARoleDao;
#Before
public void setUp() throws Exception {
derivedARoleDao = new DerivedARoleDao(DomainHelper.NEO_URL, DomainHelper.NEO_USERNAME,
DomainHelper.NEO_PASSWORD);
}
public void should_insert_data() {
IHomoSapiens start = new DerivedHomoSapiens("d-start");
IHomoSapiens end = new DerivedHomoSapiens("d-end");
IARole aRole = new DerivedARole("parent");
start.setARole(aRole);
end.setARole(aRole);
aRole.setStart(start);
aRole.setEnd(end);
IARole created = derivedARoleDao.createOrUpdate((DerivedARole)aRole);
assertThat(created, is(notNullValue()));
}
public void should_find_all() {
Iterable<DerivedARole> derivedARoles = derivedARoleDao.findAll();
assertThat(derivedARoles, is(notNullValue()));
assertThat(Iterables.isEmpty(derivedARoles), is(false));
assertTrue(Iterables.size(derivedARoles) > 0);
System.out.println(Iterables.size(derivedARoles));
}
#Test
public void should_do_crud() {
// should_insert_data();
should_find_all();
// should_find_by_id();
}
}
Am I missing something here? Or does the Neo4j OGM works well with classes (not implementing interfaces)?
The entire source code is at - https://github.com/mmwaikar/java-neo-ogm-ex (in case, it helps).
Thanks,
Manoj.
This should be fixed in 1.1.3
Till that is released, please try your code example with 1.1.3-SNAPSHOT.
You'll need to include
<repository>
<id>neo4j-snapshots</id>
<url>http://m2.neo4j.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
I am developing and spring application and for object mapping I am using ModelMapper library.
I am able to map basic class mapping but when I am trying to map 2 collection elements, source is set of enumeration with additional property like name and description and destination is pojo having id, name and description.
I have tried typemap and converters in mapping profile but I am getting exception of mapper.
And the source class is from other application(whose dependency have been added in pom.xml). I also don't want source type as an argument in setter of destination.
Ex.
SOURCE:
public class VType{
private int id;
private String name;
private String description;
}
public class VDTO{
private Set<VType> vTypes;
public Set<VType> getVTypes(){
return this.vTypes;
}
public void setVType() { //here I don't want to pass source type as an argument
//code stuff that I don't know what to do here
}
}
SOURCE ENUM:
public enum SourceVType{
V1(1, "Name1", "Desc1");
V2(2, "Name2", "Desc2");
private Integer id;
private String name;
private String description;
SourceVType(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
//getter-setter
}
Have you tried converter feature of modelmapper. You can use typemap converter to achieve this requirement.
#RunWith(JUnit4.class)
public class TempTest {
#Test
public void TestThis(){
final ModelMapper mapper = new ModelMapper();
mapper.addMappings(new PropertyMap<SrcClass, DestClass>() {
#Override
protected void configure() {
this.map().setId(this.source.getId());
this.map().setName(this.source.getName());
mapper.createTypeMap(TypeEnum.class, TypeClass.class).setConverter(
new Converter<TypeEnum, TypeClass>() {
#Override
public TypeClass convert(MappingContext<TypeEnum, TypeClass> mappingContext) {
if (mappingContext.getSource() == null) {
return null;
}
TypeEnum typeEnum = mappingContext.getSource();
TypeClass typeClass = new TypeClass();
typeClass.setId(typeEnum.getId());
typeClass.setName(typeEnum.getName());
return typeClass;
}
});
}
});
SrcClass srcObj = new SrcClass();
srcObj.setId(1);
srcObj.setName("name");
srcObj.setTypes(new HashSet<>(Arrays.asList(TypeEnum.TYPE1, TypeEnum.TYPE2)));
DestClass dstObj = mapper.map(srcObj, DestClass.class);
Assert.assertEquals(srcObj.getId(), dstObj.getId());
Assert.assertEquals(srcObj.getName(), dstObj.getName());
Assert.assertEquals(srcObj.getTypes().size(), dstObj.getTypes().size());
for(TypeClass c : dstObj.getTypes()) {
TypeEnum e = TypeEnum.getById(c.getId());
Assert.assertNotNull(e);
Assert.assertTrue(srcObj.getTypes().contains(e));
}
}
public static <Source, Result> Set<Result> convertAll(Set<Source> source, Function<Source, Result> projection)
{
Set<Result> results = new HashSet<>();
if(source == null) return results;
for (Source element : source)
{
results.add(projection.apply(element));
}
return results;
}
public static class SrcClass{
private Integer id;
private String name;
private Set<TypeEnum> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeEnum> getTypes() {
return types;
}
public void setTypes(Set<TypeEnum> types) {
this.types = types;
}
}
public static class DestClass{
private Integer id;
private String name;
private Set<TypeClass> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeClass> getTypes() {
return types;
}
public void setTypes(Set<TypeClass> types) {
this.types = types;
}
}
public static enum TypeEnum{
TYPE1(1, "Type 1")
, TYPE2(2, "Type 2")
, TYPE3(3, "Type 3")
, TYPE4(4, "Type 4");
private Integer id;
private String name;
TypeEnum(Integer id, String name) {
this.id = id;
this.name = name;
}
private static final Map<Integer, TypeEnum> byId = new HashMap<>();
private static final Map<String, TypeEnum> byName = new HashMap<>();
static {
for (TypeEnum e : TypeEnum.values()) {
if (byId.put(e.getId(), e) != null) {
throw new IllegalArgumentException("duplicate id: " + e.getId());
}
if (byName.put(e.getName(), e) != null) {
throw new IllegalArgumentException("duplicate name: " + e.getName());
}
}
}
public Integer getId() {
return this.id;
}
public String getName() { return this.name; }
public static TypeEnum getById(Integer id) {
return byId.get(id);
}
public static TypeEnum getByName(String name) {
return byName.get(name);
}
}
public static class TypeClass{
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
Here is my class,
public class FreebasePeopleResults {
public String intendedSearch;
public String weight;
public Double heightMeters;
public Integer age;
public String type;
public String parents;
public String profession;
public String alias;
public String children;
public String siblings;
public String spouse;
public String degree;
public String institution;
public String wikipediaId;
public String guid;
public String id;
public String gender;
public String name;
public String ethnicity;
public String articleText;
public String dob;
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public Double getHeightMeters() {
return heightMeters;
}
public void setHeightMeters(Double heightMeters) {
this.heightMeters = heightMeters;
}
public String getParents() {
return parents;
}
public void setParents(String parents) {
this.parents = parents;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getChildren() {
return children;
}
public void setChildren(String children) {
this.children = children;
}
public String getSpouse() {
return spouse;
}
public void setSpouse(String spouse) {
this.spouse = spouse;
}
public String getDegree() {
return degree;
}
public void setDegree(String degree) {
this.degree = degree;
}
public String getInstitution() {
return institution;
}
public void setInstitution(String institution) {
this.institution = institution;
}
public String getWikipediaId() {
return wikipediaId;
}
public void setWikipediaId(String wikipediaId) {
this.wikipediaId = wikipediaId;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEthnicity() {
return ethnicity;
}
public void setEthnicity(String ethnicity) {
this.ethnicity = ethnicity;
}
public String getArticleText() {
return articleText;
}
public void setArticleText(String articleText) {
this.articleText = articleText;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSiblings() {
return siblings;
}
public void setSiblings(String siblings) {
this.siblings = siblings;
}
public String getIntendedSearch() {
return intendedSearch;
}
public void setIntendedSearch(String intendedSearch) {
this.intendedSearch = intendedSearch;
}
}
Here is my CSV writer method
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
public class CSVUtils {
public static void writeCSVFromList(ArrayList<FreebasePeopleResults> people, boolean writeHeader) throws IOException{
//String[] header = new String []{"title","acronym","globalId","interfaceId","developer","description","publisher","genre","subGenre","platform","esrb","reviewScore","releaseDate","price","cheatArticleId"};
FileWriter file = new FileWriter("/brian/brian/Documents/people-freebase.csv", true);
// write the partial data
CsvBeanWriter writer = new CsvBeanWriter(file, CsvPreference.EXCEL_PREFERENCE);
for(FreebasePeopleResults person:people){
writer.write(person);
}
writer.close();
// show output
}
}
I keep getting output errors. Here is the error:
There is no content to write for line 2 context: Line: 2 Column: 0 Raw line:
null
Now, I know it is now totally null, so I am confused.
So it's been a while, and you've probably moved on from this, but...
The issue was actually that you weren't supplying the header to the write() method, i.e. it should be
writer.write(person, header);
Unfortunately the API is a little misleading in it's use of the var-args notation in the signature of the write() method, as it allows null to be passed in. The javadoc clearly states that you shouldn't do this, but there was no null-check in the implementation: hence the exception you were getting.
/**
* Write an object
*
* #param source
* at object (bean instance) whose values to extract
* #param nameMapping
* defines the fields of the class that must be written.
* null values are not allowed
* #since 1.0
*/
public void write(Object source, String... nameMapping) throws IOException,
SuperCSVReflectionException;
Super CSV 2.0.0-beta-1 is out now. It retains the var-args in the write() method, but fails fast if you provide a null, so you know exactly what's wrong when you get a NullPointerException with the following:
the nameMapping array can't be null as it's used to map from fields to
columns
It also includes many bug fixes and new features (including Maven support and a new Dozer extension for mapping nested properties and arrays/Collections).
I don't see where you create ArrayList<FreebasePeopleResults> people, but you might verify that it has more than one element. As an example of coding to the interface, consider using List<FreebasePeopleResults> people as the formal parameter.
Addendum: Have you been able to make this Code example: Write a file with a header work?
Example: Here's a simplified example. I think you just need to specify the nameMapping when you invoke write(). Those names determine what get methods to call via introspection.
Console output:
name,age
Alpha,1
Beta,2
Gamma,3
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
public class Main {
private static final List<Person> people = new ArrayList<Person>();
public static void main(String[] args) throws IOException {
people.add(new Person("Alpha", 1));
people.add(new Person("Beta", 2));
people.add(new Person("Gamma", 3));
ICsvBeanWriter writer = new CsvBeanWriter(
new PrintWriter(System.out), CsvPreference.STANDARD_PREFERENCE);
try {
final String[] nameMapping = new String[]{"name", "age"};
writer.writeHeader(nameMapping);
for (Person p : people) {
writer.write(p, nameMapping);
}
} finally {
writer.close();
}
}
}
public class Person {
String name;
Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
CellProcessor[] processors = new CellProcessor[] { new Optional(), new NotNull(),
new Optional(), new Optional(), new NotNull(), new Optional()};
CsvBeanWriter writer = new CsvBeanWriter(file, CsvPreference.EXCEL_PREFERENCE)
writer.write(data,properties,processors);