[Tapestry 5] Select Component - CustomSelectModel(2)

2013. 11. 4. 14:08 - 에릭투스

이건, 좀 복잡하다.. 솔직히 공부하면서, 뭔놈의 Select를 이렇게까지 써야하나 생각이 겁나들었으나, 뭐 필요한경우가 있것지..


1. SelectModel - extends AbstractSelectModel

  : t:model="SelectModel"

  : SelectModel에 List<T>형태를 생성자에 넣어줌.

  : List를 다시 풀어서, getOptions에서 List<OptionModel>형태로 리턴.

  : 즉, Select모델의 역할은 List<T>형태를 List<OptionModel>형태로 돌려주는 역할임.


 2. OptionModel - implements OptionModel

  : 실제 값 하나당 <option value="">Label</option>형태임.

  : 생성자에 T를 받고, getLabel과 getValue를 통해 Option태그 완성.


 3. Encoder - ValueEncoder

  : Encoder의 경우, 화면에 나타내는 부분을 담당.

  : OptionModel에서 value를 T로 리턴했다면, t:select 선택시 Object를 String으로 형변환 못한다는 에러가남.

  : 즉, Encoder를 통해 T의 인자값중 어느것을 value로 처리할건지 지정해주는 것이 Encoder역할.

  : toClient(T value), toValue(String clientValue)


이제 예제로 살펴보자..


1. SelectModel - extends AbstractSelectModel

 : 위에서 설명했듯, 생성자를 통해 List<T>를 받아서 getOptions()를 통해 List<OptionModel>형태로 변환한다.

package com.example.newapp.utils;

import java.util.ArrayList;
import java.util.List;

import org.apache.tapestry5.OptionGroupModel;
import org.apache.tapestry5.OptionModel;
import org.apache.tapestry5.util.AbstractSelectModel;

import com.example.newapp.domain.Person;

public class PersonSelectModel extends AbstractSelectModel {
	
	private List persons;
	
	public PersonSelectModel(List persons) {
		this.persons = persons;
	}
	
	@Override
	public List getOptionGroups() {
		return null;
	}

	@Override
	public List getOptions() {
		List list = new ArrayList();
		for(Person p : persons){
			list.add(new PersonOptionModel(p));
		}
		return list;
	}

}


2. OptionModel - implements OptionModel

 : OptionModel에서는 label과 value를 지정하는데, 만약 Value를 Object형식으로 지정하려 한다면 

 : ValueEncoder도 구현하여, 어떤 항목을 value로 지정할지 정해줘야 에러가 나지 않는다.

package com.example.newapp.utils;

import java.util.Map;

import org.apache.tapestry5.OptionModel;

import com.example.newapp.domain.Person;

public class PersonOptionModel implements OptionModel {
	
	private Person person;
	
	public PersonOptionModel(Person person) {
		this.person = person;
	}
	
	@Override
	public String getLabel() {
		return person.getFirstName()+" "+person.getLastName();
	}

	@Override
	public Object getValue() {
		System.out.println("getValue : " +person.getId());
		//return person.getId();
		return person;
	}
	
	@Override
	public boolean isDisabled() {
		return false;
	}

	@Override
	public Map getAttributes() {
		return null;
	}
}



3. ValueEncoder - Implements ValueEncoder<T>

 : 화면에 나타낼 value값을 나타낸다.


package com.example.newapp.utils;

import org.apache.tapestry5.ValueEncoder;

import com.example.newapp.data.MockDataSource;
import com.example.newapp.domain.Person;

public class PersonEncoder implements ValueEncoder {
	
	private MockDataSource source;
	public PersonEncoder(MockDataSource source) {
		this.source = source;
	}
	
	@Override
	public String toClient(Person value) {
		return String.valueOf(value.getId());
	}

	@Override
	public Person toValue(String clientValue) {
		return source.getCelebrityById(clientValue);
	}

}


4. Example Java/TML


public class ExampleChapter8 {
	
	//@Environmental
	@Inject
	private JavaScriptSupport jss;
	
	@Persist
	private MockDataSource source;
	
	public void onActivate(){
		if( source == null )
			source = new MockDataSource();
	}
	
	public SelectModel getPersonModel(){
		return new PersonSelectModel(source.getAllPersons());
	}
	
	public ValueEncoder getPersonEncoder(){
		return new PersonEncoder(source);
	}
	
	@Persist
	@Property
	private Person selectedPerson;
	
	public String getSelectedPersonName(){
		if(selectedPerson==null)
			return "";
		return selectedPerson.getFirstName()+" "+selectedPerson.getLastName();
	}
}

Example Chapter 08 - Creating Custom Component


5. MockDatasource

 : DB를 따로 사용하지 않았기때문에, 도움될까 싶어 Mock소스도 올린다.

package com.example.newapp.data;

import java.util.ArrayList;
import java.util.List;

import com.example.newapp.domain.Person;
import com.example.newapp.utils.Formats;

public class MockDataSource{
	private List persons = new ArrayList();
	
	public MockDataSource() {
		System.out.println("MockDataSource init!!");
		addPerson(new Person("Britney", "Spearce", 
			      Formats.parseDate("12/02/1981"),"192.168.1.1"));
		addPerson(new Person("Bill", "Clinton", 
			      Formats.parseDate("08/19/1946"),"192.168.1.22"));
		addPerson(new Person("Placido", "Domingo", 
			      Formats.parseDate("01/21/1941"),"192.168.21.100"));
		addPerson(new Person("Albert", "Einstein", 
			      Formats.parseDate("03/14/1879"),"192.168.1.100"));
		addPerson(new Person("Ernest", "Hemingway", 
			      Formats.parseDate("07/21/1899"),"192.168.3.1"));
		addPerson(new Person("Luciano", "Pavarotti", 
			      Formats.parseDate("10/12/1935"),"192.168.3.150"));
		addPerson(new Person("Ronald", "Reagan", 
			      Formats.parseDate("02/06/1911"),"192.168.3.210"));
		addPerson(new Person("Pablo", "Picasso", 
			      Formats.parseDate("10/25/1881"),"192.168.4.100"));
		addPerson(new Person("Blaise", "Pascal", 
			      Formats.parseDate("06/19/1623"),"192.168.5.1"));
		addPerson(new Person("Isaac", "Newton", 
			      Formats.parseDate("01/04/1643"),"192.168.5.5"));
		addPerson(new Person("Antonio", "Vivaldi", 
			      Formats.parseDate("03/04/1678"),"192.168.5.100"));
		addPerson(new Person("Niccolo", "Paganini", 
			      Formats.parseDate("10/27/1782"),"192.168.5.120"));
		addPerson(new Person("Johannes", "Kepler", 
			      Formats.parseDate("12/27/1571"),"192.168.5.130"));
		addPerson(new Person("Franz", "Kafka", 
			      Formats.parseDate("07/03/1883"),"192.168.5.140"));
		addPerson(new Person("George", "Gershwin", 
			        Formats.parseDate("09/26/1898"),"192.168.5.250"));
		addPerson(new Person("진", "형은", 
				Formats.parseDate("05/03/1988"),"192.168.10.50"));
	}
	
	public List getAllPersons(){
		return persons;
	}
	
	public Person getCelebrityById(String id){
		for(Person p : persons){
			if(Long.valueOf(id)==p.getId())
				return p;
		}
		return null;
	}
	
	public void addPerson(Person p){
		long newId = persons.size();
		p.setId(newId);
		persons.add(p);
	}
	
	public List getRange(int indexFrom, int indexTo){
		List result = new ArrayList();
		for(int i=indexFrom; i<=indexTo;i++){
			result.add(persons.get(i));
		}
		return result;
	}
}

참고 자료 : http://jumpstart.doublenegative.com.au/jumpstart/examples/select/totalcontrolobject

다른 카테고리의 글 목록

Workspace/Web Dev 카테고리의 포스트를 톺아봅니다