crescent에서 색인 설정 파일을 xml로 정의하고 있습니다.
collections.xml인데요... 본래 이걸 그냥 dom4j를 사용해서 읽어서 Map과 기타 필요한 오브젝트를 생성하는
형태로 만들어서 사용하고 있었습니다.
그러다보니.. webpage에서 이 collections.xml설정을 변경하는 기능을 추가하려보니..
저런 형태로는 다루기가 어려울 것 같아서 XML과 POJO의 변환에 관련된 라이브러리를 찾아보다가
XStream을 알게되어 처음 사용해보았습니다.
꽤 오래전부터 많이 사용되던 것 같은데..
왜 몰랐을까요 -_-;
http://xstream.codehaus.org
예제도 잘 나와있습니다.
이걸 사용해서 collections.xml을 변환해본 예제입니다. xml 자체가 그리 복잡하지 않아서..
특별히 어려운 내용은 없습니다.
XStream 사용하시는 분들께서 예제로 보시면 좋을 것 같아서 올려봅니다.
<?xml version="1.0" encoding="UTF-8"?> | |
<collections> | |
<collection name="sample"> | |
<analyzer>com.tistory.devyongsik.analyzer.KoreanAnalyzer</analyzer> | |
<indexingDirectory>/Users/need4spd/Programming/Java/crescent_index/sample</indexingDirectory> | |
<!-- indexingDirectory>/data1/lucene_index/sample</indexingDirectory --> | |
<!-- indexingDirectory>/Users/need4spd/Programming/Java/workspace/crescent/test/crescent_index/sample</indexingDirectory --> | |
<fields> | |
<!-- type : string, long, int --> | |
<field name="board_id" store="true" index="true" type="long" analyze="false" termposition="false" termoffset="false" /> | |
<field name="title" store="true" index="true" type="string" analyze="true" boost="2.0" /> | |
<field name="dscr" store="true" index="true" type="string" analyze="true" must="true" termvector="true" /> | |
<field name="creuser" store="true" index="false" type="string" analyze="false" /> | |
</fields> | |
<defaultSearchFields> | |
<defaultSearchField name="title" /> | |
<defaultSearchField name="dscr" /> | |
</defaultSearchFields> | |
<sortFields> | |
<sortField source="title" dest="title_sort" /> | |
<sortField source="board_id" dest="board_id_sort" /> | |
</sortFields> | |
</collection> | |
<collection name="sample_wiki"> | |
<analyzer>com.tistory.devyongsik.analyzer.KoreanAnalyzer</analyzer> | |
<indexingDirectory>/Users/need4spd/Programming/Java/crescent_index/sample_wiki</indexingDirectory> | |
<!-- indexingDirectory>/data1/lucene_index/glider_wiki</indexingDirectory --> | |
<!-- indexingDirectory>/Users/need4spd/Programming/Java/workspace/crescent/test/crescent_index/glider_wiki</indexingDirectory --> | |
<fields> | |
<!-- type : string, long, int --> | |
<field name="wiki_idx" store="true" index="true" type="long" analyze="false" /> | |
<field name="space_idx" store="true" index="true" type="long" analyze="false" /> | |
<field name="wiki_text" store="true" index="true" type="string" analyze="true" must="true" termvector="true" /> | |
<field name="wiki_title" store="true" index="true" type="string" analyze="true" must="true" boost="2.0" /> | |
<field name="ins_user" store="true" index="true" type="string" analyze="false" /> | |
<field name="ins_date" store="true" index="true" type="long" analyze="false" /> | |
</fields> | |
<defaultSearchFields> | |
<defaultSearchField name="wiki_title" /> | |
<defaultSearchField name="wiki_text" /> | |
</defaultSearchFields> | |
<sortFields> | |
<sortField source="ins_date" dest="ins_date_sort" /> | |
<sortField source="wiki_idx" dest="wiki_idx_sort" /> | |
</sortFields> | |
</collection> | |
</collections> |
현재 사용되고 있는 xml인데요.. XStream을 사용하기 위해서 각 엘리먼트들을 전부 클래스로 만들었습니다.
여기서는 최상위 Root를 나타내는 CrescentCollections 와 그 하위인 CrescentCollection
그리고 CrescentCollection 하위로 들어가는 CrescentCollectionField, CrescentDefaultSearchField, CrescentSortField가 만들어졌습니다.
indexingDirectory와 analyzer 부분은 CrescentCollection의 field로 들어갑니다.
package com.tistory.devyongsik.domain; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import com.thoughtworks.xstream.annotations.XStreamAlias; | |
import com.thoughtworks.xstream.annotations.XStreamImplicit; | |
import com.thoughtworks.xstream.annotations.XStreamOmitField; | |
@XStreamAlias("collections") | |
public class CrescentCollections { | |
@XStreamImplicit(itemFieldName="collection") | |
private List crescentCollections = null; | |
@XStreamOmitField | |
private Map crescentCollectionsMap = null; | |
public Map getCrescentCollectionsMap() { | |
lazyLoadMap(); | |
return crescentCollectionsMap; | |
} | |
public void setCrescentCollectionsMap( | |
Map crescentCollectionsMap) { | |
this.crescentCollectionsMap = crescentCollectionsMap; | |
} | |
public List getCrescentCollections() { | |
return crescentCollections; | |
} | |
public void setCrescentCollections(List crescentCollections) { | |
this.crescentCollections = crescentCollections; | |
} | |
@Override | |
public String toString() { | |
return "CrescentCollections [crescentCollections=" | |
+ crescentCollections + "]"; | |
} | |
} |
XStream의 annotation을 사용하였고요..
@XStreamAlias로 지정된 name 값이 엘리먼트명이 되고..
@XStreamOmitField로 지정된 field는 XML의 변환에서 제외됩니다.
@XStreamImplicit(itemFieldName="collection") private ListcrescentCollections = null;
이 부분은.. <collections></collections>가 하위에 <collection></collection>을 2개 가지고 있는데 그것을 나타내기 위한 설정입니다. 추후 실제 XML로 변환하는 코드에서 추가로 말씀을 드리겠습니다.
getter, setter 메서드는 코드에서는 생략했습니다.
CrescentCollection.javapackage com.tistory.devyongsik.domain; | |
import java.util.List; | |
import java.util.Map; | |
import com.thoughtworks.xstream.annotations.XStreamAlias; | |
import com.thoughtworks.xstream.annotations.XStreamAsAttribute; | |
import com.thoughtworks.xstream.annotations.XStreamOmitField; | |
@XStreamAlias("collection") | |
public class CrescentCollection { | |
private String analyzer; | |
@XStreamAsAttribute | |
private String name; | |
private String indexingDirectory; | |
@XStreamOmitField | |
private Map crescentFieldByName; | |
private List fields; | |
private List defaultSearchFields; | |
private List sortFields; | |
public String getAnalyzer() { | |
return analyzer; | |
} | |
} |
<collection></collection>이 가지고 있는 항목들을 표한하기 위한 설정들이 들어가있습니다.
@XStreamAsAttribute 이 설정을 가지고 있는 field는 xml에서 속성으로 표현됩니다.
<collection name="sample"> 과 같은 형태로요...
package com.tistory.devyongsik.domain; | |
import org.apache.lucene.search.BooleanClause.Occur; | |
import org.apache.lucene.search.SortField; | |
import com.thoughtworks.xstream.annotations.XStreamAlias; | |
import com.thoughtworks.xstream.annotations.XStreamAsAttribute; | |
@XStreamAlias("field") | |
public class CrescentCollectionField implements Cloneable { | |
@XStreamAsAttribute | |
private String name; | |
@XStreamAsAttribute | |
private boolean store; | |
@XStreamAsAttribute | |
private boolean index; | |
@XStreamAsAttribute | |
private String type; | |
@XStreamAsAttribute | |
private boolean analyze; | |
@XStreamAsAttribute | |
private boolean termposition; | |
@XStreamAsAttribute | |
private boolean termoffset; | |
@XStreamAsAttribute | |
private float boost; | |
@XStreamAsAttribute | |
private boolean must; | |
@XStreamAsAttribute | |
private boolean termvector; | |
} |
<field></field>는 전부 속성으로 되어있기 때문에 특별한 설정은 없고.. 다만 위 xml예에서는 각 속성이 <field></field>로 조금씩 다른데.. 위와 같이 사용하기 위해서는 필드가 전부 동일해야 하겠죠...
package com.tistory.devyongsik.domain; | |
import com.thoughtworks.xstream.annotations.XStreamAlias; | |
import com.thoughtworks.xstream.annotations.XStreamAsAttribute; | |
@XStreamAlias("defaultSearchField") | |
public class CrescentDefaultSearchField { | |
@XStreamAsAttribute | |
private String name; | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
@Override | |
public String toString() { | |
return "CrescentDefaultSearchField [name=" + name + "]"; | |
} | |
} |
<defaultSearchField/>나 <sortField/>는 거의 비슷하기 때문에 하나만...
이제 이 XML을 POJO로 변환하는 코드입니다.
XStream stream = new XStream(); | |
stream.processAnnotations(CrescentCollections.class); | |
//stream.alias( "collections", CrescentCollections.class ); | |
//stream.addImplicitCollection( CrescentCollections.class, "crescentCollections" ); | |
ResourceLoader resourceLoader = new ResourceLoader(); | |
InputStream inputStream = resourceLoader.openResource("경로"); | |
CrescentCollections crescentCollections = (CrescentCollections)stream.fromXML(inputStream); |
위와같이 해주시면 되는데...
processAnnotation은 최상위 클래스만 걸어주시면 됩니다.