Author: kmorin Date: 2009-11-23 15:44:06 +0100 (Mon, 23 Nov 2009) New Revision: 333 Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/ tags/wikengo_core-wikitty-1.0.0-alpha-2/pom.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/src/ tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/ tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/rst/ tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/rst/gwt.rst tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/site.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/pom.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/AbstractWikittyService.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntity.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityBean.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityWikitty.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Criteria.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/ExtensionFactory.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FacetTopic.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldFactory.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldType.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/JobState.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Package.html tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/PagedResult.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Tree.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/UpdateResponse.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Wikitty.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyDAO.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyException.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtension.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionMigration.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionStorage.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyProxy.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngin.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngine.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyService.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyServiceInMemory.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyStorage.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyTransaction.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyUtil.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/And.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/AssociatedRestriction.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Between.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/BinaryOperator.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Contains.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Element.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWith.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWithWilcarded.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Equals.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Greater.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/GreaterOrEqual.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/In.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Keyword.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Less.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/LessOrEqual.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Not.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/NotEquals.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Or.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Restriction.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionHelper.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionName.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Search.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SearchOperand.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/StartsWith.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SubSearch.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.uml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.umldi tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.uml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.umldi tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/site/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/AllTests.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/AbstractTestApi.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/CommonTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/ExtensionFactoryTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/SearchCriteriaTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/WikittyUtilTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/AbstractTestConformance.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/CommonTestHelper.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/SearchApiTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/StorageTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/memory/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/memory/InMemoryStorageTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/META-INF/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/META-INF/spring/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/META-INF/spring/wikitty-conformance-test.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/log4j.properties tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/pom.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyExtensionStorageJDBC.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyJDBCUtil.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyServiceJDBC.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyStorageJDBC.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/resources/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/AbstractJDBCTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/BasicImportBench.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/JDBCStorageTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/RemoteTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/SolrSearchTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/TreeTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/WikittySearchEngineTest.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVDataVisitor.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVUtils.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVWikittyBulkImport.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/GenTestData.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/ImportFeedback.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/basic-import.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/jdbc.properties tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/log4j.properties tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/noms tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/prenoms tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/protwords.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/schema.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/selected-data.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/solrconfig.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/spellwords.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/stopwords.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/synonyms.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/testData.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/pom.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/Restriction2Solr.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittyQueryParser.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittySearchEngineSolr.java tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/protwords.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/schema.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/solrconfig.xml tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/spellwords.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/stopwords.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/synonyms.txt tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/java/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/java/org/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/java/org/sharengo/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/java/org/sharengo/wikitty/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/java/org/sharengo/wikitty/solr/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/java/org/sharengo/wikitty/solr/test/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/META-INF/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/META-INF/spring/ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/log4j.properties Log: tag for wikitty 1.0.0-alpha 2 Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/pom.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/pom.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/pom.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,383 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty</artifactId> + <version>1.0.0-alpha-2</version> + + <modules> + <module>wikengo_core-wikitty-api</module> + <module>wikengo_core-wikitty-jdbc-impl</module> + <module>wikengo_core-wikitty-solr-impl</module> + </modules> + + <!--parent> + <groupId>org.sharengo.wikengo</groupId> + <artifactId>mavenpom</artifactId> + <version>1.0.0</version> + </parent--> + + <dependencyManagement> + <dependencies> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.7</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <scope>compile</scope> + <version>1.1.1</version> + </dependency> + + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.14</version> + <scope>runtime</scope> + </dependency> + + </dependencies> + </dependencyManagement> + + <distributionManagement> + <repository> + <id>nuiton</id> + <url>scpexe://nuiton.org/var/lib/maven/release</url> + </repository> + <snapshotRepository> + <id>nuiton</id> + <url>scpexe://nuiton.org/var/lib/maven/snapshot</url> + </snapshotRepository> + </distributionManagement> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>org.sharengo.wikengo.core-wikitty</name> + + <description>wikitty multi-module project</description> + <inceptionYear>2009</inceptionYear> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>pom</packaging> + + <properties> + <!-- pour un muli module on doit fixer le projectId --> + <projectId>core-wikitty</projectId> + + + <!-- java level is 1.6 --> + <maven.compile.source>1.6</maven.compile.source> + <maven.compile.target>1.6</maven.compile.target> + + <!-- default encoding --> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + + <!-- by default, use maven 2 source base dir --> + <maven.src.dir>${basedir}/src</maven.src.dir> + + <!-- to allow bad tests --> + <maven.test.testFailureIgnore>false</maven.test.testFailureIgnore> + + <!-- to skip tests (can use also profile notests) --> + <maven.test.skip>false</maven.test.skip> + + <!-- to control fork mode of tests --> + <maven.test.forkMode>once</maven.test.forkMode> + + <!-- to activate generation of reports and javadoc when doing a site --> + <maven.reports.generate>true</maven.reports.generate> + + <!-- do not use 2.5 version, it is buggy (crazy aggregate mode !) --> + <javadoc.version>2.4</javadoc.version> + + <!-- to avoid generate javadoc --> + <maven.javadoc.skip>false</maven.javadoc.skip> + + <spring.version>2.5.5</spring.version> + <hessian.version>3.1.6</hessian.version> + + </properties> + + <build> + + <pluginManagement> + + <plugins> + + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.3</version> + <configuration> + <encoding>${project.build.sourceEncoding}</encoding> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.0.2</version> + <configuration> + <source>${maven.compile.source}</source> + <target>${maven.compile.target}</target> + <encoding>${project.build.sourceEncoding}</encoding> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.4.3</version> + <configuration> + <skip>${maven.test.skip}</skip> + <testFailureIgnore>${maven.test.testFailureIgnore}</testFailureIgnore> + <forkMode>${maven.test.forkMode}</forkMode> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.1</version> + <executions> + <execution> + <id>copy-dependencies</id> + <phase>package</phase> + <goals> + <goal>copy-dependencies</goal> + </goals> + <configuration> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>false</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <outputDirectory>${project.build.directory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-war-plugin</artifactId> + <version>2.1-beta-1</version> + <configuration> + <warSourceDirectory>${maven.src.dir}/main/webapp</warSourceDirectory> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>2.2</version> + <inherited>true</inherited> + + <configuration> + <archive> + <!-- + cela fait bugger le chargement des service via + ServiceLoader donc on desactive + --> + <!--index>true</index--> + <manifest> + <mainClass>${maven.jar.main.class}</mainClass> + </manifest> + <manifestEntries> + <url>${pom.url}</url> + </manifestEntries> + </archive> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-source-plugin</artifactId> + <version>2.1</version> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <version>${javadoc.version}</version> + <configuration> + <docencoding>${project.reporting.outputEncoding}</docencoding> + <encoding>${project.reporting.outputEncoding}</encoding> + <charset>${project.reporting.outputEncoding}</charset> + <quiet>true</quiet> + <excludePackageNames>${maven.javadoc.excludePackageNames}</excludePackageNames> + <!-- uniquement a partir de javadoc 2.5 --> + <!--skip>${maven.javadoc.skip}</skip--> + </configuration> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-eclipse-plugin</artifactId> + <version>2.7</version> + <configuration> + <ajdtVersion>none</ajdtVersion> + <sourceIncludes> + <sourceInclude>**/*</sourceInclude> + </sourceIncludes> + <downloadSources>true</downloadSources> + <downloadJavadocs>true</downloadJavadocs> + <addGroupIdToProjectName>true</addGroupIdToProjectName> + </configuration> + </plugin> + + </plugins> + </pluginManagement> + + </build> + + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + + + <repositories> + + <repository> + <id>nuiton-repository</id> + <name>Repo Nuiton</name> + <url>http://maven.nuiton.org/release</url> + </repository> + + <!--repository> + <id>sharengo-ivy-repository</id> + <name>Repo Sharengo</name> + <url>http://repository.sharengo.org/maven2</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </releases> + </repository--> + + <!--repository> + <id>sharengo-maven-repository</id> + <name>Repo Sharengo</name> + <url>http://repository.sharengo.org</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </releases> + </repository--> + + <!--repository> + <id>sharengo-maven2-repository</id> + <name>Sharengo's repository</name> + <url>http://maven2.sharengo.org</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </releases> + </repository--> + + <!--repository> + <id>caucho-repository</id> + <name>Caucho Repo</name> + <url>http://caucho.com/m2</url> + </repository--> + + </repositories> + + <pluginRepositories> + + <pluginRepository> + <id>nuiton-repository</id> + <name>Repo Nuiton</name> + <url>http://maven.nuiton.org/release</url> + </pluginRepository> + + </pluginRepositories> + + <profiles> + <!-- perform only on a release stage when using the maven-release-plugin --> + <profile> + <id>release-profile</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + <build> + + <plugins> + + <!-- always compute source jar --> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- always compute javadoc jar --> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + + </build> + </profile> + + </profiles> + +</project> + + + + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/rst/gwt.rst =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/rst/gwt.rst (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/rst/gwt.rst 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,12 @@ +Probleme +======== + +GWT ne support pas: +- BigDecimal + le plus gros probleme +- PropertyChangeSupport + normalement il est possible de l'utiliser en ajouter des choses a GWT (voir avec Nicolas C.) +- Pattern + a ete deplace dans des methodes util +- String.format + peut-etre remplace par une methode util dans wikitty car seulement utilise pour les messages d'erreur avec des arguments (donc toString sur les arguments si non null) Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/site.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/site.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/src/site/site.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="${project.name}"> + + <publishDate format="dd/MM/yyyy"/> + + <bannerLeft> + <name>${project.name}</name> + <href>index.html</href> + </bannerLeft> + + <body> + <menu name="Overview"> + <item name="Accueil" href="index.html"/> + <item name="GWT problem" href="gwt.html"/> + </menu> + + <menu ref="reports"/> + + </body> +</project> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/pom.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/pom.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/pom.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,225 @@ +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty-api</artifactId> + + <parent> + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty</artifactId> + <version>1.0.0-alpha-2</version> + </parent> + + <dependencies> + + <!-- TEST --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>5.8</version> + <classifier>jdk15</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + <version>${spring.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${spring.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${spring.version}</version> + <scope>test</scope> + </dependency> + + <!-- RUNTIME --> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + <!-- COMPILE --> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xpp3</groupId> + <artifactId>xpp3</artifactId> + <version>1.1.4c</version> + </dependency> + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>org.sharengo.wikengo.core-wikitty-api</name> + + <description>public api of wikitty</description> + <inceptionYear>2009</inceptionYear> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>jar</packaging> + + <properties> + <eugene.version>1.0.0</eugene.version> + <eugengo.version>0.6.0</eugengo.version> + + <!-- where to generate sources --> + <maven.gen.dir>${project.build.directory}/generated-sources</maven.gen.dir> + + <!-- where to generate test sources --> + <maven.test.gen.dir>${project.build.directory}/generated-test-sources</maven.test.gen.dir> + <maven.test.skip>false</maven.test.skip> + <maven.test.failure.ignore>true</maven.test.failure.ignore> + </properties> + + <build> + <finalName>wikitty-api</finalName> + <resources> + <resource> + <directory>src/main/resources/</directory> + <includes> + <include>**/*.properties</include> + <include>**/*.xml</include> + </includes> + </resource> + <resource> + <directory>src/main/java/</directory> + <includes> + <include>**/*.java</include> + </includes> + </resource> + <resource> + <directory>${maven.gen.dir}/java/</directory> + <includes> + <include>**/*.java</include> + </includes> + </resource> + </resources> + + <pluginManagement> + <plugins> + <!-- Create a jar that includes all tests --> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <id>attach-test</id> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + <!-- eugene plugin --> + <plugin> + <groupId>org.nuiton.eugene</groupId> + <artifactId>maven-eugene-plugin</artifactId> + <version>${eugene.version}</version> + <dependencies> + <dependency> + <groupId>org.sharengo</groupId> + <artifactId>eugengo</artifactId> + <version>${eugengo.version}</version> + </dependency> + <!-- Meta model uml d'eclipse --> + <dependency> + <groupId>org.eclipse.uml2.uml</groupId> + <artifactId>resources</artifactId> + <version>2.1.0-v200706251652</version> + <exclusions> + <exclusion> + <groupId>org.eclipse.uml2</groupId> + <artifactId>uml</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <groupId>org.nuiton.eugene</groupId> + <artifactId>maven-eugene-plugin</artifactId> + <executions> + <execution> + <id>api generator</id> + <!-- + do not use the phase generate-XXX because it can be excecuted several times... + --> + <phase>process-sources</phase> + + <!--Configuration of model generator--> + <configuration> + <!--<addCompileDirectory>true</addCompileDirectory>--> + <zargoResources> + <input>${maven.src.dir}/main/uml/wikitty-api</input> + </zargoResources> + <includes>**/*.objectmodel</includes> + <templates>org.nuiton.eugengo.generator.WikittyMetaGenerator</templates> + <defaultPackage>org.sharengo.wikitty</defaultPackage> + <extractedPackages>org.sharengo.wikitty</extractedPackages> + <generatedPackages>org.sharengo.wikitty</generatedPackages> + </configuration> + <goals> + <goal>zargo2xmi</goal> + <goal>xmi2objectmodel</goal> + <goal>generate</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + + <!--repositories> + <repository> + <id>sharengo-maven2-repository</id> + <name>Sharengo's repository</name> + <url>http://maven2.sharengo.org</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </releases> + </repository> + </repositories--> + +</project> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/AbstractWikittyService.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/AbstractWikittyService.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/AbstractWikittyService.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,691 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.search.Search; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserFactory; + +/** + * Abstract class that new implementation must extends. + * New implementation only have three method to implement: + * <li>getSearchEngine + * <li>getExtensionStorage + * <li>getWikittyStorage + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public abstract class AbstractWikittyService implements WikittyService { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(AbstractWikittyService.class); + + // FIXME poussin 20090902 next 3 variables must be read from configuration file + /** number of thread used to import/export task */ + protected int MAX_IMPORT_EXPORT_THREAD = 1; + /** directory path where export asynchronous file are stored */ + protected String EXPORT_DIRECTORY = "/tmp/"; + /** url used by client to retrieve export file when job is ended */ + protected String EXPORT_URL = "file:///tmp/"; + + /** Executor that do import export task */ + protected ExecutorService importExportExecutor = + // TODO poussin 20090902 do thread number configurable + Executors.newFixedThreadPool(MAX_IMPORT_EXPORT_THREAD); + /** contains all import or export task, key is job id send to client */ + protected Map<String, Future<String>> importExportTask = + new HashMap<String, Future<String>>(); + + abstract protected WikittySearchEngine getSearchEngine(); + abstract protected WikittyExtensionStorage getExtensionStorage(); + abstract protected WikittyStorage getWikittyStorage(); + + /** + * Store and index wikitty object + * @param wikitty + */ + public UpdateResponse store(Wikitty wikitty) { + if (wikitty != null) { + List<Wikitty> wikitties = Arrays.asList(wikitty); + UpdateResponse result = store( wikitties ); + return result; + } else { + throw new WikittyException("You can't store null wikitty object"); + } + } + + /** + * Store and index wikitties object + * @param wikitties + */ + public UpdateResponse store(Collection<Wikitty> wikitties) { + return store(wikitties, false); + } + + /** + * Store and index wikitties object + * @param wikitties + * @param disableAutoVersionIncrement + */ + public UpdateResponse store(Collection<Wikitty> wikitties, boolean disableAutoVersionIncrement) { + try { + // update/store extension if necessary + Set<WikittyExtension> allExtensions = new HashSet<WikittyExtension>(); + for (Wikitty w : wikitties) { + // collect all extensions used by all wikitties + allExtensions.addAll(w.getExtensions()); + } + + WikittyTransaction transaction = new WikittyTransaction(); + + // create extensions update statement + List<WikittyExtensionStorage.Command> extensionStorageCommandList = + getExtensionStorage().prepare(transaction, allExtensions); + + // create wikitties update statement + List<WikittyStorage.Command> wikittyStorageCommandList = + getWikittyStorage().prepare(transaction, wikitties, disableAutoVersionIncrement); + + // create solr wikitty document for solr + List<WikittySearchEngine.Command> wikittyIndexationCommandList = + getSearchEngine().prepare(transaction, wikitties); + + // All prepare (store and index) are good + // try to commit command + UpdateResponse extUpdate = getExtensionStorage().commit(transaction, + extensionStorageCommandList); + UpdateResponse wikUpdate = getWikittyStorage().commit(transaction, + wikittyStorageCommandList); + UpdateResponse indexUpdate = getSearchEngine().commit(transaction, + wikittyIndexationCommandList); + + UpdateResponse result = new UpdateResponse(); + + // prepare update client response + result.add(extUpdate); + result.add(wikUpdate); + result.add(indexUpdate); + + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + public List<String> getAllExtensionIds() { + List<String> result = getExtensionStorage().getAllExtensionIds(); + return result; + } + + public List<WikittyExtension> getAllExtensions(boolean lastVersion) { + List<WikittyExtension> result = getExtensionStorage().getAllExtensions(lastVersion); + return result; + } + + /** + * Save just one extension + * @param exts + * @throws java.io.IOException + */ + public UpdateResponse storeExtension(Collection<WikittyExtension> exts) { + WikittyTransaction transaction = new WikittyTransaction(); + List<WikittyExtensionStorage.Command> commands = + getExtensionStorage().prepare(transaction, exts); + UpdateResponse result = getExtensionStorage().commit(transaction, + commands); + + return result; + } + + /** + * Load extension from id. Id is 'name[version]' + * @param id + * @return + */ + public WikittyExtension restoreExtension(String id) { + WikittyExtension result = getExtensionStorage().restore(id); + return result; + } + + public Wikitty restore(String id) { + if (!getWikittyStorage().exists(id)) { + // object doesn't exist, we return null + return null; + } + + if (getWikittyStorage().isDeleted(id)) { + // object deleted, we return null + return null; + } + + Wikitty result = getWikittyStorage().restore(id); + return result; + } + + public List<Wikitty> restore(List<String> id) { + List<Wikitty> result = new ArrayList<Wikitty>(); + for(String k : id) { + Wikitty w = restore(k); + if ( w != null ) { + result.add(w); + } + } + return result; + } + + public void delete(String id){ + delete(Arrays.asList(id)); + } + + public void delete(Collection<String> ids){ + // work only on valid id + List<String> idList = new LinkedList<String>(ids); + for (Iterator<String> i = idList.iterator(); i.hasNext();) { + String id = i.next(); + // test if wikitty exists + if (!getWikittyStorage().exists(id)) { + // don't exist, remove this id in id list + i.remove(); + } + if (getWikittyStorage().isDeleted(id)) { + // already deleted, remove this id in id list + i.remove(); + } + } + + WikittyTransaction transaction = new WikittyTransaction(); + List<WikittyStorage.Command> storeCommands = + getWikittyStorage().delete(idList); + List<WikittySearchEngine.Command> indexCommands = + getSearchEngine().delete(transaction, idList); + + getWikittyStorage().commit(transaction, storeCommands); + getSearchEngine().commit(transaction, indexCommands); + } + + + public PagedResult<Wikitty> findAllByCriteria(Criteria criteria) { + PagedResult<String> resultId = getSearchEngine().findAllByCriteria(criteria); + PagedResult<Wikitty> result = resultId.cast(getWikittyStorage()); + return result; + } + + public Wikitty findByCriteria(Criteria criteria) { + criteria.setFirstIndex(0).setEndIndex(1); + PagedResult<Wikitty> pages = findAllByCriteria(criteria); + if (pages.size() > 0) { + Wikitty result = pages.getFirst(); + return result; + } else { + return null; + } + } + + + public void addLabel(String wikittyId, String label) { + Wikitty w = restore(wikittyId); + w.addExtension(LabelImpl.extensions); + LabelImpl l = new LabelImpl(w); + l.addLabels(label); + store(l.getWikitty()); + } + + + public PagedResult<Wikitty> findAllByLabel(String label, int firstIndex, int endIndex) { + LabelImpl l = new LabelImpl(); + l.addLabels(label); + Criteria criteria = Search.query(l.getWikitty()).criteria() + .setFirstIndex(firstIndex).setEndIndex(endIndex); + PagedResult<Wikitty> result = findAllByCriteria(criteria); + return result; + } + + + public Wikitty findByLabel(String label) { + LabelImpl l = new LabelImpl(); + l.addLabels(label); + Criteria criteria = Search.query(l.getWikitty()).criteria(); + Wikitty result = findByCriteria(criteria); + return result; + } + + + public Set<String> findAllAppliedLabels(String wikittyId) { + Wikitty w = restore(wikittyId); + Label l = new LabelImpl(w); + Set<String> result = l.getLabels(); + return result; + } + + + public Tree restoreTree(String wikittyId) { + Wikitty w = restore(wikittyId); + if(w == null) { + return null; + } + + if ( !w.hasExtension(TreeNode.EXT_TREENODE) ) { + throw new WikittyException(String.format( + "Wikitty '%s' do not handle extension %s", + wikittyId, TreeNode.EXT_TREENODE )); + } + Tree tree = new Tree(); + TreeNode node = new TreeNodeImpl( w ); + tree.setNode( node ); + + TreeNodeImpl exempleNode = new TreeNodeImpl(); + exempleNode.setParent(wikittyId); + + Criteria criteria = Search.query(exempleNode.getWikitty()).criteria() + .setFirstIndex(0).setEndIndex(ALL_ELEMENTS); + PagedResult<Wikitty> childNodes = findAllByCriteria(criteria); + for( Wikitty childNode : childNodes.getAll() ) { + tree.addChild( restoreTree(childNode.getId()) ); + } + Set<String> children = node.getChildren(); + if (children != null) { + for (String childrenId : children) { + tree.addElement(childrenId); + } + } + + return tree; + } + + public Map<TreeNode, Integer> restoreChildren(String wikittyId) { + Wikitty w = restore(wikittyId); + if(w == null) { + return null; + } + + if ( !w.hasExtension(TreeNode.EXT_TREENODE) ) { + throw new WikittyException(String.format( + "Wikitty '%s' do not handle extension %s", + wikittyId, TreeNode.EXT_TREENODE )); + } + + Map<TreeNode, Integer> result = new LinkedHashMap<TreeNode, Integer>(); + + Map<String, Integer> search = getSearchEngine().findAllChildren(w); + Set<Entry<String, Integer>> children = search.entrySet(); + for (Entry<String, Integer> child : children) { + Integer count = child.getValue(); + + String id = child.getKey(); + Wikitty wikitty = restore(id); + TreeNode node = new TreeNodeImpl(wikitty); + + result.put(node, count); + } + + return result; + } + + public Wikitty restoreVersion(String wikittyId, String version) { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Class used for import process, this class retain numberForCommit object + * before to send it to storage. + */ + static protected class WikittyBatchUpdate { + // TODO poussin 20090902 do configurable numberForCommit + protected int numberForCommit = 1000; + int currentAdded = 0; + protected Map<String, WikittyExtension> exts = + new HashMap<String, WikittyExtension>(); + protected List<Wikitty> wikitties = new LinkedList<Wikitty>(); + + WikittyService ws; + + public WikittyBatchUpdate(WikittyService ws) { + this.ws = ws; + } + + public void addExtension(WikittyExtension ext) { + exts.put(ext.getId(), ext); + inc(); + } + + public void addWikitty(Wikitty w) { + wikitties.add(w); + inc(); + } + + /** + * search extension in local extension list and if missed restore + * extension from internal WikittyService + * @param id + * @return + */ + public WikittyExtension getExtension(String id) { + WikittyExtension result = exts.get(id); + if (result == null) { + result = ws.restoreExtension(id); + } + return result; + } + + public void flush() { + ws.storeExtension(exts.values()); + ws.store(wikitties, true); + exts.clear(); + wikitties.clear(); + currentAdded = 0; + } + + + protected void inc() { + currentAdded++; + if (currentAdded >= numberForCommit) { + flush(); + } + } + } + + + public void syncImportFromXml(String xml) { + Reader reader = new StringReader(xml); + ImportTask task = new ImportTask(this, reader); + task.run(); + } + + + public void syncImportFromUri(String uri) { + try { + URL url = new URL(uri); + Reader reader = new InputStreamReader(url.openStream()); + ImportTask task = new ImportTask(this, reader); + task.run(); + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + + public String asyncImportFromUri(String uri) { + try { + URL url = new URL(uri); + Reader reader = new InputStreamReader(url.openStream()); + ImportTask task = new ImportTask(this, reader); + FutureTask<String> future = new FutureTask<String>(task, null); + importExportExecutor.submit(future); + + String jobId = UUID.randomUUID().toString(); + importExportTask.put(jobId, future); + return jobId; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + + static public class ImportTask implements Runnable { + protected WikittyService ws; + protected Reader reader; + + public ImportTask(WikittyService ws, Reader reader) { + this.ws = ws; + this.reader = reader; + } + + public void run() { + try { + XmlPullParserFactory factory = XmlPullParserFactory.newInstance( + System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null); + factory.setNamespaceAware(true); + XmlPullParser xpp = factory.newPullParser(); + xpp.setInput(reader); + + WikittyExtension ext = null; + Wikitty w = null; + String CDATA = null; + + WikittyBatchUpdate batchUpdate = new WikittyBatchUpdate(ws); + + long time = System.currentTimeMillis(); + + int eventType = xpp.getEventType(); + do { + String objectVersion = null; + if (eventType == xpp.START_DOCUMENT) { + log.info("start XML import at " + new Date()); + } else if (eventType == xpp.END_DOCUMENT) { + time = System.currentTimeMillis() - time; + log.info("XML import in (ms)" + time); + } else if (eventType == xpp.START_TAG) { + String name = xpp.getName(); + if ("extension".equals(name)) { + String extName = xpp.getAttributeValue(null, "name"); + String version = xpp.getAttributeValue(null, "version"); + String requires = xpp.getAttributeValue(null, "requires"); + ext = new WikittyExtension(extName, version, requires, new LinkedHashMap<String, FieldType>()); + } else if ("object".equals(name)) { + String id = xpp.getAttributeValue(null, "id"); + objectVersion = xpp.getAttributeValue(null, "version"); + String extensions = xpp.getAttributeValue(null, "extensions"); + w = new Wikitty(id); + String[] extensionList = extensions.split(","); + for (String extId : extensionList) { + WikittyExtension e = batchUpdate.getExtension(extId); + w.addExtension(e); + } + } + } else if (eventType == xpp.END_TAG) { + String name = xpp.getName(); + if ("extension".equals(name)) { + batchUpdate.addExtension(ext); + ext = null; + } else if ("object".equals(name)) { + w.setVersion(objectVersion); + batchUpdate.addWikitty(w); + w = null; + } else if (ext != null && "field".equals(name)) { + FieldType type = new FieldType(); + String fieldName = WikittyUtil.parseField(CDATA, type); + ext.addField(fieldName, type); + } else if (w != null) { + String[] fq = name.split("\\."); + String extensionName = fq[0]; + String fieldName = fq[1]; + FieldType fieldType = w.getFieldType(name); + if(fieldType.isCollection()) { + w.addToField(extensionName, fieldName, CDATA); + } else { + w.setField(extensionName, fieldName, CDATA); + } + } + } else if (eventType == xpp.TEXT) { + CDATA = xpp.getText(); + } + eventType = xpp.next(); + } while (eventType != xpp.END_DOCUMENT); + + // don't forget to flush batchUpdate :) + batchUpdate.flush(); + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + } // end ImportTask + + public String asyncExportAllByCriteria(Criteria criteria) { + try { + criteria.setFirstIndex(0).setEndIndex(ALL_ELEMENTS); + PagedResult<Wikitty> pageResult = findAllByCriteria(criteria); + + String jobId = UUID.randomUUID().toString(); + + File file = new File(EXPORT_DIRECTORY, jobId); + String url = EXPORT_URL + jobId; + Writer result = new FileWriter(file); + ExportTask task = new ExportTask(pageResult, result); + FutureTask<String> future = new FutureTask<String>(task, url); + importExportExecutor.submit(future); + + importExportTask.put(jobId, future); + return jobId; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + + public String syncExportAllByCriteria(Criteria criteria) { + criteria.setFirstIndex(0).setEndIndex(ALL_ELEMENTS); + PagedResult<Wikitty> pageResult = findAllByCriteria(criteria); + StringWriter result = new StringWriter(); + ExportTask task = new ExportTask(pageResult, result); + task.run(); + return result.toString(); + } + + + static public class ExportTask implements Runnable { + protected PagedResult<Wikitty> pageResult; + protected Writer result; + + public ExportTask(PagedResult<Wikitty> pageResult, Writer result) { + this.pageResult = pageResult; + this.result = result; + } + + public void run() { + try { + // keep extension already done + Set<String> extDone = new HashSet<String>(); + result.write("<wikengo>\n"); + for (Wikitty w : pageResult.getAll()) { + String extensionList = ""; + for (WikittyExtension ext : w.getExtensions()) { + String id = ext.getId(); + extensionList += "," + id; + if (!extDone.contains(id)) { + extDone.add(id); + result.write(" <extension name='" + ext.getName() + "' version='" + ext.getVersion() + "' requires='" + ext.getRequires() + "'>\n"); + for (String fieldName : ext.getFieldNames()) { + String def = ext.getFieldType(fieldName).toDefinition(fieldName); + result.write(" <field>" + def + "</field>\n"); + } + result.write(" </extension>\n"); + } + } + if (!"".equals(extensionList)) { + // delete first ',' + extensionList = extensionList.substring(1); + } + result.write(" <object id='" + w.getId() + "' version='" + w.getVersion() + "' extensions='" + extensionList + "'>\n"); + for (String fieldName : w.fieldNames()) { + FieldType type = w.getFieldType(fieldName); + if (type.isCollection()) { + for (Object o : (List) w.getFqField(fieldName)) { + result.write(" <" + fieldName + ">" + WikittyUtil.toString(type, o) + "</" + fieldName + ">\n"); + } + } else { + result.write(" <" + fieldName + ">" + WikittyUtil.toString(type, w.getFqField(fieldName)) + "</" + fieldName + ">\n"); + } + } + result.write(" </object>\n"); + } + result.write("</wikengo>\n"); + } catch (IOException eee) { + throw new WikittyException(eee); + } + } + } // end ExportTask + + + public JobState infoJob(String jobId) { + try { + Future<String> future = importExportTask.get(jobId); + JobState result = new JobState(); + if (future.isDone()) { + result.status = "done"; + result.resourceUri = future.get(); + } else if (future.isCancelled()) { + result.status = "cancelled"; + } else { + result.status = "inProgress"; + } + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + + public void cancelJob(String jobId) { + Future future = importExportTask.get(jobId); + future.cancel(true); // true to kill process, perhaps to strong ? + } + + + public void freeJobResource(String jobId) { + Future<String> future = importExportTask.remove(jobId); + if (future != null) { + File file = new File(EXPORT_DIRECTORY, jobId); + file.delete(); + } + } + + /** + * Changes the data directory + * @param newDataDir the new data directory path + * @param oldDataDir the old data directory path. + * If null, the data in the old directory will not be copied. + */ + public void changeDataDir(String newDataDir, String oldDataDir) { + getSearchEngine().changeDataDir(newDataDir, oldDataDir); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntity.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntity.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntity.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,92 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.io.Serializable; +import java.util.Collection; + +/** + * Used as parent interface to all Business class + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface BusinessEntity extends Serializable, Cloneable { + + public String getWikittyId(); + public String getWikittyVersion(); + /** + * Only framework can use this method + * @param version + */ + public void setWikittyVersion(String version); + + /** + * Return list of all extensions for this object + * @return + */ + public void addExtension(WikittyExtension extension); + + /** + * Return list of all extensions for this object + * @return + */ + public Collection<WikittyExtension> getExtensions(); + + /** + * Return list of all extension names for this object + * @return + */ + public Collection<String> getExtensionNames(); + + /** + * Return list of all field for this object + * @param ext + * @return + */ + public Collection<String> getExtensionFields(String ext); + + /** + * Return field value for the specifique extension and field + * @param ext + * @param fieldName + * @return + */ + public Object getField(String ext, String fieldName); + + /** + * set field value for the specifique extension and field. + * This method don't check the type of value for this field. + * @param ext + * @param fieldName + * @param value + * @return + */ + public void setField(String ext, String fieldName, Object value); + + /** + * Return the field type + * @param ext + * @param fieldName + * @return + */ + public FieldType getFieldType(String ext, String fieldName); +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityBean.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityBean.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityBean.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,102 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class BusinessEntityBean implements BusinessEntity { + + private static final long serialVersionUID = 1L; + + protected String id; + protected String version; + + /** + * Map is LinkedHashMap to maintains order like user want + * key: extension name + * value: extension definition + */ + protected Map<String, WikittyExtension> extensions = + new LinkedHashMap<String, WikittyExtension>(); + /** + * key: field name prefixed by extension name (dot separator) + * value: value of field + */ + protected Map<String, Object> fieldValue = new HashMap<String, Object>(); + + public String getWikittyId() { + return id; + } + + public String getWikittyVersion() { + return version; + } + + public void setWikittyVersion(String version) { + this.version = version; + } + + @Override + public void addExtension(WikittyExtension extension) { + extensions.put(extension.getName(), extension); + } + + @Override + public Collection<WikittyExtension> getExtensions() { + return extensions.values(); + } + + + public Collection<String> getExtensionNames() { + Collection<String> result = extensions.keySet(); + return result; + } + + public Collection<String> getExtensionFields(String ext) { + WikittyExtension extension = extensions.get(ext); + Collection<String> result = extension.getFieldNames(); + return result; + } + + public Object getField(String ext, String fieldName) { + String key = ext + "$" + fieldName; + Object result = fieldValue.get(key); + return result; + } + + public void setField(String ext, String fieldName, Object value) { + String key = ext + "$" + fieldName; + fieldValue.put(key, value); + } + + public FieldType getFieldType(String ext, String fieldName) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityWikitty.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityWikitty.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/BusinessEntityWikitty.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,159 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.beans.PropertyChangeSupport; +import java.util.Collection; +import java.util.Collections; + +/** + * + * @author poussin + * @version $Revision$ + * + * Each business object will inherit of this class. + * + * Last update: $Date$ + * by : $Author$ + */ +public class BusinessEntityWikitty implements BusinessEntity { + + private static final long serialVersionUID = 1L; + + /** used to add property change support to wikitty object */ + protected PropertyChangeSupport propertyChange = new PropertyChangeSupport(this); + + protected Wikitty wikitty; + + public BusinessEntityWikitty(Wikitty wi) { + setWikitty(wi); + } + + public BusinessEntityWikitty() { + setWikitty( new Wikitty() ); + } + + public String getWikittyId() { + String result = getWikitty().getId(); + return result; + } + + public String getWikittyVersion() { + String result = getWikitty().getVersion(); + return result; + } + + public void setWikittyVersion(String version) { + getWikitty().setVersion(version); + } + + @Override + public void addExtension(WikittyExtension extension) { + getWikitty().addExtension(extension); + } + + @Override + public Collection<WikittyExtension> getExtensions() { + return getWikitty().getExtensions(); + } + + public void setWikitty(Wikitty wikitty) { + wikitty = upgradeData(wikitty, getStaticExtensions()); + for ( WikittyExtension ext : getStaticExtensions() ) { + wikitty.addExtension(ext); + } + this.wikitty = wikitty; + } + + public Wikitty getWikitty() { + return wikitty; + } + + public Collection<String> getExtensionNames() { + Collection<String> result = getWikitty().getExtensionNames(); + return result; + } + + public Collection<String> getExtensionFields(String ext) { + Collection<String> result = getWikitty().getExtension(ext).getFieldNames(); + return result; + } + + public FieldType getFieldType(String ext, String fieldName) { + FieldType result = getWikitty().getExtension(ext).getFieldType(fieldName); + return result; + } + + public Object getField(String ext, String fieldName) { + Object result = null; + FieldType type = getFieldType(ext, fieldName); + if(type.isCollection()) { + result = getWikitty().getFieldAsObject(ext, fieldName); + } else { + switch(type.getType()) { + case BOOLEAN: + result = getWikitty().getFieldAsBoolean(ext, fieldName); + break; + case DATE: + result = getWikitty().getFieldAsDate(ext, fieldName); + break; + case NUMERIC: + result = getWikitty().getFieldAsBigDecimal(ext, fieldName); + break; + case STRING: + result = getWikitty().getFieldAsString(ext, fieldName); + break; + case WIKITTY: + result = getWikitty().getFieldAsString(ext, fieldName); + break; + default: + result = getWikitty().getFieldAsObject(ext, fieldName); + break; + } + } + return result; + } + + public void setField(String ext, String fieldName, Object value) { + getWikitty().setField(ext, fieldName, value); + propertyChange.firePropertyChange(fieldName,null,value); + } + + public Collection<WikittyExtension> getStaticExtensions() { + return Collections.emptyList(); + } + + protected Wikitty upgradeData(Wikitty wikitty, Collection<WikittyExtension> extensions) { + for (WikittyExtension ext : extensions) { + if (wikitty.hasExtension(ext.getName())) { + WikittyExtension oldExt = wikitty.getExtension(ext.getName()); + String newVersion = ext.getVersion(); + String oldVersion = oldExt.getVersion(); + if (WikittyUtil.versionGreaterThan(newVersion, oldVersion)) { + WikittyExtensionMigration migration = + WikittyExtensionMigration.migrationRegistry.get(ext.getName()); + if (migration != null) { + wikitty = migration.migrate(wikitty, oldExt, ext); + } + } + } + } + return wikitty; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Criteria.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Criteria.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Criteria.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,229 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.beans.XMLDecoder; +import java.beans.XMLEncoder; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.search.Restriction; + +/** + * Criteria represent the search on the wikitty with restriction on field and + * informations on facet, paggination and sortting. + *<p> + * For search multiple extension use ALL_EXTENSIONS as extension name and + * specify field type. + * <p> + * Example : Criteria.ALL_EXTENSIONS + Criteria.SEPARATOR + <fieldName> + Criteria.SEPARATOR + FieldType.TYPE.<fieldType> + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class Criteria { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(Criteria.class); + + /** Use to not limit result */ + static public int ALL_ELEMENTS = -1; + + /** Search on all extension */ + static public String ALL_EXTENSIONS = "*"; + + /** Separator between extension name, field name and type */ + static public String SEPARATOR = "."; + + /** + * Criteria can have name this help for presentation and is very + * useful for facet created by criteria + */ + protected String name; + + /** All restriction on fields */ + private Restriction restriction; + + /** First index to get result */ + private int firstIndex = 0; + /** Last index to get result */ + private int endIndex = ALL_ELEMENTS; + + /** Facet on criteria */ + private List<Criteria> facetCriteria; + /** Facet on field */ + private List<String> facetField; + + /** Sort ascending on fields */ + private List<String> sortAscending; + /** Sort descending on fields */ + private List<String> sortDescending; + + /** + * Default constuctor + */ + public Criteria() { + } + + /** + * Create named criteria + * @param name + */ + public Criteria(String name) { + this.name = name; + } + + /** + * Deserialize xml to criteria + * @param xml + * @return criteria + */ + public static Criteria fromXML(String xml) { + InputStream inputStream = new ByteArrayInputStream(xml.getBytes()); + XMLDecoder decoder = new XMLDecoder(inputStream); + Criteria criteria = (Criteria) decoder.readObject(); + return criteria; + } + + /** + * Serialize criteria to xml + * @param criteria + * @return xml string + */ + public static String toXML(Criteria criteria) { + OutputStream outputStream = new ByteArrayOutputStream(); + XMLEncoder encoder = new XMLEncoder(outputStream); + encoder.writeObject(criteria); + encoder.close(); + String result = outputStream.toString(); + return result; + } + + public Restriction getRestriction() { + return restriction; + } + + public void setRestriction(Restriction restriction) { + this.restriction = restriction; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getFirstIndex() { + return firstIndex; + } + + public Criteria setFirstIndex(int firstIndex) { + this.firstIndex = firstIndex; + return this; + } + + public int getEndIndex() { + return endIndex; + } + + public Criteria setEndIndex(int endIndex) { + this.endIndex = endIndex; + return this; + } + + public List<Criteria> getFacetCriteria() { + return facetCriteria; + } + + public Criteria addFacetCriteria(Criteria criteria) { + if (facetCriteria == null) { + facetCriteria = new ArrayList<Criteria>(); + } + facetCriteria.add(criteria); + return this; + } + + public Criteria setFacetCriteria(Criteria[] facetCriteria) { + this.facetCriteria = Arrays.asList(facetCriteria); + return this; + } + + public List<String> getFacetField() { + return facetField; + } + + public Criteria addFacetField(String field) { + if (facetField == null) { + facetField = new ArrayList<String>(); + } + facetField.add(field); + return this; + } + + public Criteria setFacetField(String[] facetField) { + this.facetField = Arrays.asList(facetField); + return this; + } + + public List<String> getSortAscending() { + return sortAscending; + } + + public Criteria addSortAscending(String field) { + if(sortAscending == null) { + sortAscending = new ArrayList<String>(); + } + sortAscending.add(field); + return this; + } + + public Criteria setSortAscending(String[] sortAscending) { + this.sortAscending = Arrays.asList(sortAscending); + return this; + } + + public List<String> getSortDescending() { + return sortDescending; + } + + public Criteria addSortDescending(String field) { + if(sortDescending == null) { + sortDescending = new ArrayList<String>(); + } + sortDescending.add(field); + return this; + } + + public Criteria setSortDescending(String[] sortDescending) { + this.sortDescending = Arrays.asList(sortDescending); + return this; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/ExtensionFactory.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/ExtensionFactory.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/ExtensionFactory.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,38 @@ +package org.sharengo.wikitty; + +import java.util.LinkedHashMap; + +import org.sharengo.wikitty.FieldType.TYPE; + +public class ExtensionFactory { + + private String name; + private String version; + private String requiredExtension; + + private LinkedHashMap<String, FieldType> fields; + + private ExtensionFactory(String name, String version) { + this.name = name; + this.version = version; + this.fields = new LinkedHashMap<String, FieldType>(); + } + + public static ExtensionFactory create(String name, String version) { + return new ExtensionFactory(name, version); + } + + public FieldFactory addField(String name, TYPE fieldType) { + return new FieldFactory(this, name, fieldType); + } + + public WikittyExtension extension() { + WikittyExtension ext = new WikittyExtension( name, version, requiredExtension, fields ); + return ext; + } + + protected void add(String fieldName, FieldType fieldType) { + fields.put(fieldName, fieldType); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FacetTopic.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FacetTopic.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FacetTopic.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,62 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import java.io.Serializable; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class FacetTopic implements Serializable { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(FacetTopic.class); + + private static final long serialVersionUID = 1L; + + protected String facetName; + protected String topicName; + protected int count; + + public FacetTopic(String facetName, String topicName, int count) { + this.facetName = facetName; + this.topicName = topicName; + this.count = count; + } + + public String getFacetName() { + return facetName; + } + + public String getTopicName() { + return topicName; + } + + public int getCount() { + return count; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldFactory.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldFactory.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldFactory.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,49 @@ +package org.sharengo.wikitty; + +import org.sharengo.wikitty.FieldType.TYPE; + +public class FieldFactory { + + private ExtensionFactory parentFactory; + private String fieldName; + private TYPE type; + private int minOccur = 0, maxOccur = 1; + private boolean unique = false; + + public FieldFactory(ExtensionFactory parentFactory, String fieldName, TYPE type) { + this.parentFactory = parentFactory; + this.fieldName = fieldName; + this.type = type; + } + + public FieldFactory addField( String name, TYPE type ) { + append(); + return parentFactory.addField(name, type); + } + + public WikittyExtension extension() { + append(); + return parentFactory.extension(); + } + + private void append() { + FieldType fieldType = new FieldType( type, minOccur, maxOccur, unique, minOccur > 0 ); + parentFactory.add( fieldName, fieldType ); + } + + public FieldFactory maxOccur(int max) { + maxOccur = max; + return this; + } + + public FieldFactory minOccur(int min) { + minOccur = min; + return this; + } + + public FieldFactory unique() { + unique = true; + return this; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldType.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldType.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/FieldType.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,225 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class FieldType implements Serializable { + + static public enum TYPE { + BOOLEAN, DATE, NUMERIC, STRING, WIKITTY; + + /** + * convert string to TYPE, this methode accept not trimed and not well + * cased string (difference with valueOf) + * @param name + * @return TYPE else exception is throw + */ + public static TYPE parse(String name) { + TYPE result = valueOf(name.trim().toUpperCase()); + return result; + } + } + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(FieldType.class); + + private static final long serialVersionUID = 1L; + + public static final int NOLIMIT = Integer.MAX_VALUE; + + TYPE type; + int lowerBound; + int upperBound; + boolean unique = false; + boolean notNull = false; + + /** used to store tag/value used by client side ex: editor=xhtml */ + Map<String, String> tagValues = new HashMap<String, String>(); + + public FieldType() { + } + + public FieldType(TYPE type, int lowerBound, int upperBound) { + this.type = type; + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } + + public FieldType(TYPE type, int lowerBound, int upperBound, boolean unique, boolean notNull) { + this.type = type; + this.lowerBound = lowerBound; + this.upperBound = upperBound; + this.unique = unique; + this.notNull = notNull; + } + + public void addTagValue(String tag, String value) { + tagValues.put(tag, value); + } + + public String getTagValue(String tag) { + String result = tagValues.get(tag); + return result; + } + + /** + * Return true if this field have upperBound > 1 + * @return + */ + public boolean isCollection() { + return upperBound > 1; + } + + /** + * Return string definition for this field + * @param name field name used for definition + * @return + */ + public String toDefinition(String name) { + String result = type + " " + name; + if (lowerBound != 0 || upperBound != 0) { + if (upperBound != NOLIMIT) { + result += "[" + lowerBound + "-" + upperBound + "]"; + } else { + result += "[" + lowerBound + "-*]"; + } + } + if (isUnique()) { + result += " unique"; + } + if (isNotNull()) { + result += " not null"; + } + for (String tag : tagValues.keySet()) { + result += " " + tag + "=" + tagValues.get(tag); + } + return result; + } + + /** + * Convert value in argument in right type for this FieldType. Don't support + * collection + * + * @param value value to convert + * @return object in type of this FieldType + */ + protected Object getContainedValidObject( Object value ) { + Object result = null; + switch (type) { + case DATE: + result = WikittyUtil.toDate(value); break; + case NUMERIC: + result = WikittyUtil.toBigDecimal(value); break; + case BOOLEAN: + result = WikittyUtil.toBoolean(value); break; + case STRING: + result = WikittyUtil.toString(value); break; + default: + // if type is not found then type is business type + // and is wikity object + result = WikittyUtil.toWikitty(value); break; + } + return result; + } + + /** + * Return a valid value for this field. + * @param value is casted if possible to an actual correct value. + * @return + */ + public Object getValidValue( Object value ) throws WikittyException { + if (value == null && isNotNull()) { + throw new WikittyException("Value can't be null for this field"); + } + + Object result; + if (value == null) { + result = null; + } else if (isCollection()) { + if ( !(value instanceof Collection) ) { + throw new WikittyException( "A collection is expected for type " + + type.name() + "[" + lowerBound + " - " + upperBound + "]" ); + } + Collection<Object> col; + if (isUnique()) { + col = new HashSet<Object>(); + } else { + col = new ArrayList<Object>(); + } + + // copy all value in new collections + for ( Object o : (Collection) value ) { + col.add( getContainedValidObject(o) ); + } + result = col; + } else { + result = getContainedValidObject(value); + } + return result; + } + + /** + * test if value in argument is valide for this field type + * @param value to test + * @return true if value is valid + */ + public boolean isValidValue(Object value) { + return getValidValue(value) != null; + } + + public TYPE getType() { + return type; + } + + public int getLowerBound() { + return lowerBound; + } + + public int getUpperBound() { + return upperBound; + } + + public boolean isUnique() { + return unique; + } + + public boolean isNotNull() { + return notNull; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/JobState.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/JobState.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/JobState.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,41 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class JobState { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(JobState.class); + + String status; // or enum + /** if is an export, resourceUri is not null when job is ended */ + String resourceUri; // generated resource URI on that job + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Package.html =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Package.html (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Package.html 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,203 @@ +<h1>Wikitty API documentation</h1> + +<h2>Extensions version management</h2> + +The extension version number have to be managed by the developer who writes or +modify the extension. + +When we modify an extension in a model, a developer have to remember to update +the version tag/value. + +<h2>Objects deletion management</h2> + +The objects deleted are only marked as deleted, like that it will be possible to +restore a deleted object in future implementations. + +The deleted objects are not indexed anymore (and so do not appear in search +results). + +If we try to get a deleted object by its id, null is returned. + +We cannot save a deleted object until we do a undelete on it. + +<h2>Wikitties attributes</h2> + +It is possible to define several things for a wikitty field : + +<ul> + <li>its type (String)</li> + <li>its name (String)</li> + <li>its cardinality ([1-n])</li> + <li>if it is unique (unique), for the lists it will be reprensted by a Set, for + not-list objects it means that two objects cannot have the same value for + this field (constraint not implemented for now). + </li> + <li>if it has to be not null, there is no mean, in the modeler to indicate it, + and so it is not possible to generate it. + </li> + <li>Tag/values (tag=value). It is possible to create as many tag/values as we + want. You can then get them by FieldType.getTagValue(tagName). This can be + useful to put a tag 'editor' used by UI and that allows to put a specific + editor for a field (e.g. a html editor for a String field) + </li> +</ul> + +<h2>PropertyChangeListener</h2> + +The field modification listeners management is diretly done by the wikitty +object. The name of the field is the concatenation of the extension name and the +field name ([extName].[fieldName]). + +<h2>Search API</h2> + +<h3>General points</h3> + +The search are made by example (a model dto), or from a search 'Criteria' object. + +This criteria contains restrictions that will be turned into searhc request. + +The criteria can be built from the utility class 'Search' that allows to express, +via instructions, all the restrictions. + +The Search operations return a reference to an object of the same type allowing +to continue expressing other criteria. + +This allows to write quickly and easily search expressions with the Search API's +help (and auto-completion will help even more). + +The Search operations names are really short and syntaxically close to bash +conditional expressions... + +<h3>List of criteria operations</h3> +We will find : <ul> + <li> eq : to express equality</li> + <li> neq : to express difference (not equals)</li> + <li> le, lt : respectively for inclusive and exclusive inferiority operations + (less than, less or equals)</li> + <li> ge, gt : respectively for inclusive and exclusive superiority operations + (greater than, greater or equals)</li> + <li> sw : to express an expression beginning (start with)</li> + <li> ew : to express an expression ending (end with)</li> + <li> in : to express a list of possible values</li> +</ul> + +<h3>Disjunction operation, disjunction group</h3> +By default, each restrictions express by the above expressions are added to a +list of conjunctions (logical AND). + +It is possible to express disjunctions (logical OR) using the or operation. + +The restriction following the or is then in disjunction with the one preceding +it. + +If other restrictions are added after that, they are attached to the previous +conjunction. + +To express a group of disjunction, we can call the or operation between each +restriction or call the group operation with the 'OR' type. + +In this last case, you will need to close the groupe by calling the end operation. + +<h3>Associative search</h3> +It is possible to express associative search, i.e. search for which some criteria +are based on objects linked by a reference (link or foreign key notion). + +Then, the associated (fieldName) operation allows to +Il est possible d'exprimer des recherches associatives, c'est à dire des recherches pour lesquelles certains critères portent sur un objet liÊ par une rÊfÊrence (notion de lien, ou de clÊ Êtrangère).<br> +Ainsi, l'opÊration associated( fieldName ) permet de faire porter les critères suivant cette opÊration sur les objets liÊ via ce champ.<br> +Le rÊsultat sera une conjonction (ET) entre les critères exprimÊs avant l'opÊration associated sur l'objet 'principal' (il peut ne pas y en avoir), et dont la ou les rÊfÊrences associÊe rÊpondent aux critères exprimÊs après le associated.<br> +Tout cela est beaucoup plus clair par l'exemple ;-)<br> + +I want to find all paints between 15 and 25 euros in the Hardware section. + +This search can be expressed ina more concrete way using API via : + +"I search all products wich price is between 15 and 25 euros, which name starts +by 'Paint', and which associated section, using the 'section' field, have the +name 'Hardware'". + +It is built using the following operations : + +<pre> + RestrictionDto dto = Search.query() + .bw( "Product.selling_price", "15", "25") + .sw( "Produit.article_name", "Paint") + .associated( "Product.section" ) + .eq( "Section.name", "Hardware" ) + .criteria(); +</pre> + + +<h2>Data migration</h2> + +When the list of wikitty extensions is modified, either: +<ul> + <li>we deleted an extension, the data stays in the wikitty</li> + <li>we added an extension, nothing is done but we can add data for the new + fields</li> + <li>we modified an extension + <li>deleted an extension field : the data stays but are no more + accessible</li> + <li>added a field to the extension : nothing is done but we can add data + for the new field</li> + <li>modified a field type: + <ul> + <li>API knows how to convert it, nothing to do (e.g. int->String)</li> + <li>The type has been deeply modified (e.g. String->List<int<): + you have to implement an extension migration sub-class + (WikittyExtensionMigration) and save it so that it is used when + necessary.</li> + </ul> + </li> +</ul> + +<p>An object is converted when it is loaded in its BusinessEntity, but is is not + automatically save, it is saved only if a store is called on the client side. +</p> + +<p>It is also possible to force the migration searching all the objects with the +modified extension, load them in WikittyDtos and save them.</p> +<pre> +Wikitty w = new Wikitty(); +w.addExtension(myModifiedExtension); +WikittyDto dto = new WikittyDto(w); +PagedResult<WikittyDto> result = proxy.findAllByExample(dto, 0, Proxy.ALL_ELEMENTS); +proxy.store(result.getAll()); +</pre> + +<h2>Import Wikitties</h2> + +When importing XML file, if an object has a version nmber, then if in the +database there is no object or if the object has a version number less or equal +than the imported version number, the xml file data overwrite the database data. + +If the database version number is greater than the imported version number, the +imported object is rejected and an exception is thrown. + +If the imported object had no version number, in all cases, it overwrite the +database data and the object version number is incremented if it was present in +database. + +Modifications to do on implementation : +<ul> + <li>During xml file reading and loading into wikitty object, if there is no + version number in xml flux, the version number is null instead of + defaultversion.</li> + <li>Take into account that during wikitty save, the version number can be + null, do the appropriate treatment</li> +</ul> + +If an object in database was deleted and we try to import it, we throw an +exception. + +<h2>TODO</h2> +<ul> +<li>while generating BusinessEntity, if 2 extensions have the same method, + suffix the next ones with xxxxxxForExtensionName</li> +<li>Think about object search problem if its extensions have been modified. + If you do a search by example, we add the extension list in the request, the + new BusinessEntity has more extensions, we do not find the old objects. If + we do a search by criteria/example, the criterie field cannot exist in the + index and so the object is not returned in results even if we put '*' as + field value.</li> +</ul> \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/PagedResult.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/PagedResult.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/PagedResult.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,198 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class PagedResult<T> implements Serializable { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(PagedResult.class); + + private static final long serialVersionUID = 1L; + + /** indice element in global search result */ + protected int firstIndice; + /** total number of result if we call the query for all possible result */ + protected int numFound; + /** query really executed */ + protected String queryString; + /** list of result in the wanted interval */ + protected List<T> results; + /** facet asked or null if no facet */ + protected Map<String, List<FacetTopic>> facets; + + public PagedResult(int FirstIndice, int numFound, String queryString, + Map<String, List<FacetTopic>> facets, List<T> results) { + this.firstIndice = FirstIndice; + this.numFound = numFound; + this.queryString = queryString; + this.facets = facets; + this.results = Collections.unmodifiableList(results); + } + + /** + * Assume that this PagedResult contains wikitty id as result and + * return new PagedResult with Wikitty instance + * + * @param wikittyStorage storage used to instanciate Wikitty + * @param fqFieldName list of field that must be loaded, other fields + * can be not loaded + * @return + */ + public PagedResult<Wikitty> cast(WikittyStorage wikittyStorage, + String ... fqFieldName) { + List<Wikitty> wikitties = wikittyStorage.restore( + (Collection<String>)getAll(), fqFieldName); + PagedResult<Wikitty> result = new PagedResult<Wikitty>( + firstIndice, numFound, queryString, facets, wikitties); + return result; + } + + /** + * Converte all result to the wanted type and return new PagedResult with + * this new result list. If some result don't have the right extension (clazz) + * this extension is automatically added if autoconvert is true. Else + * an exception is throwed when result without extension is found. + * + * When you used autoconvert = false, you have a potentialy probleme when + * you have modified a BusinessEntity to have new extension and all your + * wikitty object are not uptodate in database. + * + * @param clazz + * @param autoconvert + * @return + */ + public <E extends BusinessEntityWikitty> PagedResult<E> cast( + Class<E> clazz, boolean autoconvert) { + List<E> castedResult = new ArrayList<E>(results.size()); + E sample = WikittyUtil.newInstance(clazz); + Collection<WikittyExtension> wantedExtension = sample.getStaticExtensions(); + for (T t : results) { + if (t == null) { + castedResult.add(null); + } else { + Wikitty w = null; + if (t instanceof Wikitty) { + w = (Wikitty)t; + } else if (t instanceof BusinessEntityWikitty) { + w = ((BusinessEntityWikitty) t).getWikitty(); + } else { + throw new WikittyException(String.format( + "Illegal object result class '%s' can't convert it to wikitty", + t.getClass().getName(), clazz.getName())); + } + + Collection<WikittyExtension> wikittyExtension = w.getExtensions(); + if (wikittyExtension.containsAll(wantedExtension)) { + E e = WikittyUtil.newInstance(clazz, (Wikitty) t); + castedResult.add(e); + } else { + throw new WikittyException(String.format( + "Illegal object result class '%s' can't convert it to '%s'" + + "there is no same extension %s != %s", + t.getClass().getName(), clazz.getName(), + wikittyExtension, wantedExtension)); + } + } + } + PagedResult<E> result = new PagedResult<E>( + firstIndice, numFound, queryString, facets, castedResult); + return result; + } + + public int getFirstIndice() { + return firstIndice; + } + + public int getNumFound() { + return numFound; + } + + public String getQueryString() { + return queryString; + } + + /** + * Return name of all facet used in query + * @return + */ + public Collection<String> getFacetNames() { + Collection<String> result = facets.keySet(); + return result; + } + + /** + * Return all topic for the specified facet + * @param facetName name of the wanted facet + * @return + */ + public List<FacetTopic> getTopic(String facetName) { + List<FacetTopic> result = facets.get(facetName); + return result; + } + + /** + * Return the firstIndice element in result or throw an exception if no element + * available + * @return + */ + public T getFirst() { + T result = get(0); + return result; + } + + public T get(int i) { + T result = results.get(i); + return result; + } + + /** + * Return unmodifiable list of all result + * @return + */ + public List<T> getAll() { + return results; + } + + /** + * Return the number of result in this object + * @return + */ + public int size() { + int result = results.size(); + return result; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Tree.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Tree.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Tree.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,39 @@ +package org.sharengo.wikitty; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class Tree { + + TreeNode node; + List<Tree> children; + // List<String> elements; + + public void setNode(TreeNode node) { + this.node = node; + } + + public void addChild(Tree tree) { + getChildren().add( tree ); + } + + public List<Tree> getChildren() { + if ( children == null ) { + children = new ArrayList<Tree>(); + } + return children; + } + + public void addElement(String id) { + node.addChildren(id); + } + + public Set<String> getElements() { + return node.getChildren(); + } + + public String getName() { + return node.getName(); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/UpdateResponse.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/UpdateResponse.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/UpdateResponse.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,75 @@ +package org.sharengo.wikitty; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class UpdateResponse { + + protected Map<String, String> idVersionMap = new HashMap<String, String>(); + protected Map<String, Date> idDeletionDateMap = new HashMap<String, Date>(); + + public UpdateResponse() { + super(); + idVersionMap = new HashMap<String, String>(); + } + + /** + * Merge all update passed in argument in local update list + * @param update + */ + public void add(UpdateResponse update) { + idVersionMap.putAll(update.idVersionMap); + idDeletionDateMap.putAll(update.idDeletionDateMap); + } + + public void addVersionUpdate( String id, String version ) { + idVersionMap.put(id, version); + } + + public void addDeletionDateUpdate(String id, Date date) { + idDeletionDateMap.put(id, date); + } + + public void update(BusinessEntity e) { + if (e instanceof BusinessEntityWikitty) { + update((BusinessEntityWikitty) e); + } else if (e instanceof BusinessEntityBean) { + update((BusinessEntityBean) e); + } + } + + public void update(BusinessEntityBean e) { + // update version + String id = e.getWikittyId(); + String version = idVersionMap.get(id); + if (version != null) { + e.setWikittyVersion(version); + } + } + + public void update(BusinessEntityWikitty e) { + update(e.getWikitty()); + } + + /** + * Update data directly in object passed in argument. + * Actualy only version and deletion date are updated. + * And internaly wikitty object is marked clean (not dirty) + * @param e + */ + public void update(Wikitty e) { + // update version + String id = e.getId(); + String version = idVersionMap.get(id); + if (version != null) { + e.setVersion(version); + } + Date date = idDeletionDateMap.get(id); + if (date != null) { + e.setDeleteDate(date); + } + e.clearDirty(); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Wikitty.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Wikitty.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/Wikitty.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,629 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.AbstractList; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class Wikitty implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * technical id for this wikitty object. id must be never null + */ + protected String id; + /** current version of this wikitty object */ + protected String version = WikittyUtil.DEFAULT_VERSION; + /** if not null, date of deletion, if date this object is marked as deleted */ + protected Date deleteDate = null; + + /** used to add property change support to wikitty object */ + protected PropertyChangeSupport propertyChange = new PropertyChangeSupport(this); + + /** + * key: field name prefixed by extension name (dot separator) + * value: value of field + */ + protected Map<String, Object> fieldValue = new HashMap<String, Object>(); + /** + * all field name currently modified (field name = extension . fieldname) + */ + protected Set<String> fieldDirty = new HashSet<String>(); + /** + * Map is LinkedHashMap to maintains order like user want + * key: extension name + * value: extension definition + */ + protected Map<String, WikittyExtension> extensions = + new LinkedHashMap<String, WikittyExtension>(); + + + public Wikitty() { + this(null); + } + + public Wikitty(String id){ + if(id == null) { + this.id = WikittyUtil.genUID(); + } else { + this.id = id; + } + } + + public synchronized void addPropertyChangeListener( + PropertyChangeListener listener) { + propertyChange.addPropertyChangeListener(listener); + } + + + public synchronized void removePropertyChangeListener( + PropertyChangeListener listener) { + propertyChange.removePropertyChangeListener(listener); + } + + + public synchronized void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + propertyChange.addPropertyChangeListener(propertyName, listener); + } + + + public synchronized void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + propertyChange.removePropertyChangeListener(propertyName, listener); + } + + public String getId() { + return id; + } + + public boolean isDeleted() { + boolean result = deleteDate != null; + return result; + } + + public Date getDeleteDate() { + return deleteDate; + } + + /** + * Server only used + * @param delete + */ + public void setDeleteDate(Date delete) { + this.deleteDate = delete; + } + + /** + * mark field as dirty + * @param ext + * @param fieldName + */ + protected void setFieldDirty(String ext, String fieldName, + Object oldValue, Object newValue) { + String key = ext + "." + fieldName; + fieldDirty.add(key); + version = WikittyUtil.incrementMinorRevision(version); + propertyChange.firePropertyChange(key, oldValue, newValue); + } + + public void addExtension(WikittyExtension ext) { + String required = ext.getRequires(); + if (required != null && !required.isEmpty() && + !extensions.containsKey(required)) { + throw new WikittyException(String.format( + "You try to add extension '%s' that" + + " required not available extension '%s' in this wikitty", + ext.getName(), required)); + } + extensions.put(ext.name, ext); + } + + public void addExtension(List<WikittyExtension> exts) { + for (WikittyExtension ext : exts) { + extensions.put(ext.name, ext); + } + } + + public boolean hasExtension(String extName) { + return extensions.containsKey(extName); + } + + public boolean hasField(String extName, String fieldName) { + boolean result = false; + WikittyExtension ext = extensions.get(extName); + if (ext != null) { + result = ext.getFieldType(fieldName) != null; + } + return result; + } + + public WikittyExtension getExtension(String ext) { + WikittyExtension result = extensions.get(ext); + return result; + } + + public Collection<String> getExtensionNames() { + Collection<String> result = extensions.keySet(); + return result; + } + + public Collection<WikittyExtension> getExtensions() { + Collection<WikittyExtension> result = extensions.values(); + return result; + } + + public Collection<WikittyExtension> getExtensionDependencies(String ext, boolean recursively) { + Collection<WikittyExtension> result = new HashSet<WikittyExtension>(); + Collection<WikittyExtension> all = extensions.values(); + for (WikittyExtension dependency : all) { + String requires = dependency.getRequires(); + if(requires != null && !requires.isEmpty() && requires.equals(ext)) { + result.add(dependency); + if(recursively) { + String dependencyName = dependency.getName(); + Collection<WikittyExtension> dependencies = getExtensionDependencies(dependencyName, recursively); + result.addAll(dependencies); + } + } + } + return result; + } + + /** + * return field type for the given fieldName. + * @param fieldName fully qualified fieldName extension.fieldname + * @return field type + */ + public FieldType getFieldType(String fqfieldName) { + try { + String[] field = fqfieldName.split("\\."); + WikittyExtension ext = getExtension(field[0]); + if (ext == null) { + throw new WikittyException(String.format( + "extension '%s' doesn't exists", field[0])); + } else { + String fieldName = field[1]; + int crochet = fieldName.indexOf("["); + if (crochet != -1) { + fieldName = fieldName.substring(0, crochet); + } + FieldType result = ext.getFieldType(fieldName); + if (result == null) { + throw new WikittyException(String.format( + "field '%s' doesn't exists on extension '%s'", fieldName, field[0])); + + } + return result; + } + } catch (Exception eee) { + throw new WikittyException( + String.format("Field %s is not a fully qualified field name", fqfieldName), + eee + ); + } + } + + public void setField(String ext, String fieldName, Object value) { + if (! hasField(ext, fieldName)) { + String def = ""; + for ( WikittyExtension extension : extensions.values() ) { + def += extension.toDefinition() + "\n"; + } + throw new WikittyException(String.format( + "field '%s' is not valid, extensions definition : %s", ext + "." + fieldName, def)); + } + String key = ext + "." + fieldName; + + // take old value if needed + Object oldValue = null; + if (propertyChange.hasListeners(key)) { + oldValue = fieldValue.get(key); + } + + // put new value + FieldType fieldType = getExtension(ext).getFieldType(fieldName); + Object validValue = fieldType.getValidValue(value); + fieldValue.put(key, validValue); + + // mark field dirty and call listener + setFieldDirty(ext, fieldName, oldValue, validValue); + + propertyChange.firePropertyChange(fieldName, oldValue, validValue); + } + + public Object getFieldAsObject(String ext, String fieldName) { + if (!hasField(ext, fieldName)) { + throw new WikittyException(String.format( + "field '%s' is not a valid field", + ext + "." + fieldName)); + } + String key = ext + "." + fieldName; + Object result = fieldValue.get(key); + return result; + } + + public boolean getFieldAsBoolean(String ext, String fieldName) { + Object value = getFieldAsObject(ext, fieldName); + try { + boolean result = WikittyUtil.toBoolean(value); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid boolean", + ext + "." + fieldName), eee); + } + } + + public BigDecimal getFieldAsBigDecimal(String ext, String fieldName) { + Object value = getFieldAsObject(ext, fieldName); + try { + BigDecimal result = WikittyUtil.toBigDecimal(value); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid numeric", + ext + "." + fieldName), eee); + } + } + + public int getFieldAsInt(String ext, String fieldName) { + try { + BigDecimal value = getFieldAsBigDecimal(ext, fieldName); + int result = value.intValue(); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid int", + ext + "." + fieldName), eee); + } + } + + public long getFieldAsLong(String ext, String fieldName) { + try { + BigDecimal value = getFieldAsBigDecimal(ext, fieldName); + long result = value.longValue(); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid int", + ext + "." + fieldName), eee); + } + } + + public float getFieldAsFloat(String ext, String fieldName) { + try { + BigDecimal value = getFieldAsBigDecimal(ext, fieldName); + float result = value.floatValue(); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid float", + ext + "." + fieldName), eee); + } + } + + public double getFieldAsDouble(String ext, String fieldName) { + try { + BigDecimal value = getFieldAsBigDecimal(ext, fieldName); + double result = value.doubleValue(); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid float", + ext + "." + fieldName), eee); + } + } + + public String getFieldAsString(String ext, String fieldName) { + Object value = getFieldAsObject(ext, fieldName); + try { + String result = WikittyUtil.toString(value); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid String", + ext + "." + fieldName), eee); + } + } + + public Date getFieldAsDate(String ext, String fieldName) { + Object value = getFieldAsObject(ext, fieldName); + try { + Date result = WikittyUtil.toDate(value); + return result; + } catch (WikittyException eee) { + throw new WikittyException(String.format( + "field '%s' is not a valid Date", + ext + "." + fieldName), eee); + } + } + + /** + * return wikitty id and not wikitty objet because this method can be call + * on server or client side and it's better to keep conversion between id + * and objet to the caller + * @param ext extension name where this field must to be + * @param fieldName the field name + * @return id of wikitty object or null + * @throws org.sharengo.wikitty.WikittyException + */ + public String getFieldAsWikitty(String ext, String fieldName) { + Object value = getFieldAsObject(ext, fieldName); + String result = WikittyUtil.toWikitty(value); + return result; + } + + /** + * If object is a set, it is automatically transform to list. + * @param <E> + * @param clazz + * @return unmodifiable list + */ + public <E> List<E> getFieldAsList(String ext, String fieldName, final Class<E> clazz) { + try { + final Collection<E> collection = (Collection<E>) getFieldAsObject(ext, fieldName); + if (collection != null) { + // return unmodiable collection that check type of element + return new AbstractList<E>() { + List<E> contained = new ArrayList<E>(collection); + @Override public E get(int index) { + return WikittyUtil.cast( contained.get(index), clazz ); + } + @Override public int size() { + return contained.size(); + } + }; + } + return null; + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't add value to field '%s'", + ext + "." + fieldName), eee); + } + } + + /** + * + * @param <E> + * @param clazz + * @return unmodifiable list + */ + public <E> Set<E> getFieldAsSet(String ext, String fieldName, final Class<E> clazz) { + try { + final Set<E> result = (Set<E>) getFieldAsObject(ext, fieldName); + if (result != null) { + // return unmodifable Set + return new AbstractSet<E>() { + Set<E> contained = result; + @Override public int size() { + return contained.size(); + } + @Override + public Iterator<E> iterator() { + return new Iterator<E>() { + Iterator containedIterator = contained.iterator(); + public boolean hasNext() { + return containedIterator.hasNext(); + } + + public E next() { + Object o = containedIterator.next(); + return WikittyUtil.cast(o, clazz); + } + + public void remove() { + throw new UnsupportedOperationException("Not supported operation"); + } + }; + + } + }; + } + return result; + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't add value to field '%s'", + ext + "." + fieldName), eee); + } + } + + public void addToField(String ext, String fieldName, Object value) { + try { + FieldType fieldType = getExtension(ext).getFieldType(fieldName); + Collection col = (Collection) getFieldAsObject(ext, fieldName); + if (col == null) { + if (fieldType.isUnique()) { + col = new HashSet(); + } else { + col = new ArrayList(); + } + col.add( value ); + setField(ext, fieldName, col); + // no call dirty, because already done in setField + } else { + // check upper bound only if col exists, + // because ask upper bound == 0 is ridiculous + + if (fieldType.isUnique()) { + if (!col.contains(value)) { + // only add if not already in collection (unique) + if (col.size() + 1 > fieldType.getUpperBound()) { + // if upper bound reached, throw an exception + throw new WikittyException(String.format( + "Can't add value for field '%s', upper bound is reached", + ext + "." + fieldName)); + } + col.add(value); + setFieldDirty(ext, fieldName, null, col); + } + } else { + if (col.size() + 1 > fieldType.getUpperBound()) { + throw new WikittyException(String.format( + "Can't add value for field '%s', upper bound is reached", + ext + "." + fieldName)); + } + col.add(value); + setFieldDirty(ext, fieldName, null, col); + } + } + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't add value to field '%s'", + ext + "." + fieldName), eee); + } + } + + public void removeFromField(String ext, String fieldName, Object value) { + try { + Collection col = (Collection) getFieldAsObject(ext, fieldName); + if (col != null) { + FieldType type = getExtension(ext).getFieldType(fieldName); + if (col.contains(value)) { + if (col.size() - 1 < type.getLowerBound()) { + throw new WikittyException(String.format( + "Can't remove value for field '%s', lower bound is reached", + ext + "." + fieldName)); + } else { + if (col.remove(value)) { + // field is dirty only if remove is done + setFieldDirty(ext, fieldName, null, col); + } + } + } + } + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't remove value for field '%s'", + ext + "." + fieldName), eee); + } + } + + public void clearField(String ext, String fieldName) { + FieldType type = getExtension(ext).getFieldType(fieldName); + if (type.getLowerBound() > 0) { + throw new WikittyException(String.format( + "Can't clear values for field '%s', lower bound is > 0", + ext + "." + fieldName)); + } + try { + Collection col = (Collection) getFieldAsObject(ext, fieldName); + if (col != null) { + col.clear(); + setFieldDirty(ext, fieldName, null, col); + } + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't clear value for field '%s'", + ext + "." + fieldName), eee); + } + } + + @Override + public boolean equals(Object obj) { + boolean result = false; + if (obj instanceof Wikitty) { + Wikitty other = (Wikitty) obj; + result = id.equals(other.id); + } + return result; + } + + public Iterable<String> fieldNames() { + return fieldValue.keySet(); + } + + public Object getFqField(String fqFieldName) { + return fieldValue.get(fqFieldName); + } + + public String getVersion() { + return version; + } + + /** + * Server only used + * @param version + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * Server only used + * @param version + */ + public void clearDirty() { + fieldDirty.clear(); + } + + /** + * Server only used + * @param fieldName fqn (ex: extensionName.fieldName) + * @param value new value + */ + public void setFqField(String fieldName, Object value) { + FieldType fieldType = getFieldType(fieldName); + Object validValue = fieldType.getValidValue(value); + fieldValue.put(fieldName, validValue); + } + + public boolean isEmpty() { + return fieldValue.isEmpty(); + } + + @Override + public String toString() { + boolean cr = true; + String str = "[" + getId() + ":" + getVersion() + "] {"; + for ( String extName : getExtensionNames() ) { + WikittyExtension ext = getExtension(extName); + str += (cr ? "\n" : "") + "\t<" + extName + ">\n"; + cr = false; + for ( String fieldName : ext.getFieldNames() ) { + str += "\t\t" + fieldName + " = " + getFieldAsString(extName, fieldName) + "\n"; + } + } + str += "}"; + return str; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyDAO.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyDAO.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyDAO.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,172 @@ +package org.sharengo.wikitty; + +import java.lang.reflect.ParameterizedType; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public abstract class WikittyDAO<E extends BusinessEntityWikitty> { + + protected static Log log = LogFactory.getLog( WikittyDAO.class ); + + private WikittyProxy proxy; + private Class<E> clazz; + + public WikittyDAO() { + clazz = getActualClassType(); + } + + private Class<E> getActualClassType() { + ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass(); + Class<E> clazz = (Class<E>)type.getActualTypeArguments()[0]; + return clazz; + } + + public void addLabel(String wikittyId, String label) { + proxy.addLabel(wikittyId, label); + } + + public String asyncExportAllByCriteria(Criteria criteria) { + return proxy.asyncExportAllByCriteria(criteria); + } + + public String asyncExportAllByExample(E e) { + return proxy.asyncExportAllByExample(e); + } + + public String asyncImportFromUri(String uri) { + return proxy.asyncImportFromUri(uri); + } + + public void cancelJob(String jobId) { + proxy.cancelJob(jobId); + } + + public void delete(Collection<String> ids) { + proxy.delete(ids); + } + + public void delete(String id) { + proxy.delete(id); + } + + public boolean equals(Object obj) { + return proxy.equals(obj); + } + + public Set<String> findAllAppliedLabels(String wikittyId) { + return proxy.findAllAppliedLabels(wikittyId); + } + + public PagedResult<E> findAllByCriteria(Criteria criteria) { + return proxy.findAllByCriteria(clazz, criteria); + } + + public PagedResult<E> findAllByExample(E e, int firstIndex, int endIndex, String... fieldFacet) { + return proxy.findAllByExample(e, firstIndex, endIndex, fieldFacet); + } + + public PagedResult<Wikitty> findAllByLabel(String label, int firstIndex, int endIndex) { + return proxy.findAllByLabel(label, firstIndex, endIndex); + } + + public E findByCriteria(Criteria criteria) { + return proxy.findByCriteria(clazz, criteria); + } + + public E findByExample(E e) { + return proxy.findByExample(e); + } + + public Wikitty findByLabel(String label) { + return proxy.findByLabel(label); + } + + public void freeJobResource(String jobId) { + proxy.freeJobResource(jobId); + } + + public WikittyService getWikittyService() { + return proxy.getWikittyService(); + } + + public int hashCode() { + return proxy.hashCode(); + } + + public JobState infoJob(String jobId) { + return proxy.infoJob(jobId); + } + + public List<E> restore(List<String> id, boolean checkExtension) { + return proxy.restore(clazz, id, checkExtension); + } + + public List<E> restore(List<String> id) { + return proxy.restore(clazz, id); + } + + public E restore(String id, boolean checkExtension) { + Class<E> clazz = getActualClassType(); + return proxy.restore(clazz, id, checkExtension); + } + + public E restore(String id) { + return proxy.restore(clazz, id); + } + + public Tree restoreTree(String wikittyId) { + return proxy.restoreTree(wikittyId); + } + + public Map<E, Integer> restoreChildren(String wikittyId) { + Class<E> clazz = getActualClassType(); + return proxy.restoreChildren(clazz, wikittyId); + } + + public Wikitty restoreVersion(String wikittyId, String version) { + return proxy.restoreVersion(wikittyId, version); + } + + public void setWikittyService(WikittyService wikittyService) { + proxy.setWikittyService(wikittyService); + } + + public E store(E e) { + return proxy.store(e); + } + + public List<E> store(List<E> objets) { + return proxy.store(objets); + } + + public String syncExportAllByCriteria(Criteria criteria) { + return proxy.syncExportAllByCriteria(criteria); + } + + public String syncExportAllByExample(E e) { + return proxy.syncExportAllByExample(e); + } + + public void syncImportFromUri(String uri) { + proxy.syncImportFromUri(uri); + } + + public void syncImportFromXml(String xml) { + proxy.syncImportFromXml(xml); + } + + public String toString() { + return proxy.toString(); + } + + public void setProxy(WikittyProxy proxy) { + this.proxy = proxy; + } + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyException.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyException.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyException.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,44 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public WikittyException(String message) { + super(message); + } + + public WikittyException(Exception eee) { + super(eee); + } + + public WikittyException(String message, Exception eee) { + super(message, eee); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtension.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtension.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtension.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,175 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyExtension implements Serializable { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyExtension.class); + + private static final long serialVersionUID = 1L; + + /** + * name of this extension + */ + protected String name; + /** + * name of other extension needed to put this extension to object + */ + protected String requires; + + /** + * use to know version objet, when you change field number, type or other + * you must change version number. + */ + protected String version = WikittyUtil.DEFAULT_VERSION; + + /** + * fields use ordered map, to keep order insertion of field + * key: field name + * value: field type + */ + protected LinkedHashMap<String, FieldType> fields = new LinkedHashMap<String, FieldType>(); + + public WikittyExtension(String name) { + if (name == null) { + throw new IllegalArgumentException("Name must not be null"); + } + this.name = name; + } + + public WikittyExtension(String name, String version, + String requires, LinkedHashMap<String, FieldType> fields) { + if (name == null) { + throw new IllegalArgumentException("Name must not be null"); + } + if (version == null) { + throw new IllegalArgumentException("Version must not be null"); + } + this.name = name; + this.version = version; + this.requires = requires; + if (fields != null) { + this.fields = fields; + } + } + + /** + * compute id for extension name and version in argument + * @param name + * @param version + * @return + */ + static public String computeId(String name, String version) { + String result = name + "[" + version + "]"; + return result; + } + + static public String computeName(String id) { + int i = id.lastIndexOf("["); + String result = id.substring(0, i); + return result; + } + + static public String computeVersion(String id) { + int b = id.lastIndexOf("["); + int e = id.lastIndexOf("]"); + String result = id.substring(b+1, e); + return result; + } + + public String getId() { + String result = computeId(getName(), getVersion()); + return result; + } + + public String getName() { + return name; + } + + public String getVersion() { + return version; + } + + public String getRequires() { + return requires; + } + + public FieldType getFieldType(String fieldName) { + return fields.get(fieldName); + } + + public List<String> getFieldNames() { + List<String> result = new ArrayList<String>(fields.keySet()); + return result; + } + + public void addField(String fieldName, FieldType type) { + fields.put(fieldName, type); + } + + @Override + public int hashCode() { + return getId().hashCode(); + } + + + @Override + public boolean equals(Object obj) { + boolean result = false; + if (obj instanceof WikittyExtension) { + WikittyExtension other = (WikittyExtension)obj; + result = this.getId().equals(other.getId()); + } + return result; + } + + @Override + public String toString() { + return getId(); + } + + public String toDefinition() { + String res = "Extension " + getId() + "{\n"; + for ( String fieldName : fields.keySet() ) { + res += fields.get(fieldName).toDefinition(fieldName) + "\n"; + } + res += "}"; + return res; + } + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionMigration.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionMigration.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionMigration.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,55 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import java.util.HashMap; +import java.util.Map; + +/** + * Interface used to migrate Wikitty data from one WikittyExtension version + * to another version + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface WikittyExtensionMigration { + + // TODO poussin 20090902 permit configuration of migrationRegistry by spring + /** + * use to put migration class for extension. + * key: extensionName, value: migration class + */ + static public Map<String, WikittyExtensionMigration> migrationRegistry = + new HashMap<String, WikittyExtensionMigration>(); + + /** + * Migrate wikitty data from oldExt version to newExt + * @param wikitty Wikitty object that contains data in old version + * extension format + * @param oldExt old extension definition + * @param newExt new extension definition + * @return same wikitty as argument if nothing to do, or new wikitty + * if some modification is done + */ + public Wikitty migrate(Wikitty wikitty, + WikittyExtension oldExt, WikittyExtension newExt); +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionStorage.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionStorage.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyExtensionStorage.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,91 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.util.Collection; +import java.util.List; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface WikittyExtensionStorage { + + /** + * Prepare command's List needed to update the storage + * @param allExtensions + * @param update + * @return + */ + public List<Command> prepare(WikittyTransaction transaction, + Collection<WikittyExtension> allExtensions) throws WikittyException; + + /** + * Commit all modification command passed in argument + * @param extensionStorageCommandList + * @return information usefull for client side update data + */ + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> extensionStorageCommandList); + + /** + * Return true if id exists in storage + * @param id + * @return + */ + public boolean exists(String id); + + /** + * Return all extension ids + * @return + */ + public List<String> getAllExtensionIds(); + + /** + * Return all extensions (ex: "extName[version])") + * @param lastVersion if true, returns only the last version of each extension + * @return + */ + public List<WikittyExtension> getAllExtensions(boolean lastVersion); + + /** + * return last version available for specified extension name + * @param extName name of extension + * @return last version availble for this version, or null if extension + * doesn't exist + */ + public String getLastVersion(String extName); + + /** + * Restore one extension from storage, if not found an exception is throw + * @param id extension id to restore + * @return + */ + public WikittyExtension restore(String id) throws WikittyException; + + /** + * Command update + */ + static public interface Command {} + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyProxy.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyProxy.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyProxy.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,416 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.sharengo.wikitty.search.Element; +import org.sharengo.wikitty.search.Search; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyProxy { + + static final public int ALL_ELEMENTS = WikittyService.ALL_ELEMENTS; + + protected WikittyService wikittyService; + + public WikittyService getWikittyService() { + return wikittyService; + } + + public void setWikittyService(WikittyService wikittyService) { + this.wikittyService = wikittyService; + } + + public <E extends BusinessEntity> E store(E e) { + Wikitty w = WikittyUtil.beanToWikitty(e); + UpdateResponse resp = wikittyService.store(w); + resp.update(e); + return e; + } + + /** + * Store to WikittyService objects. + * @param objets list of BeanDto + * @return + */ + public <E extends BusinessEntity> List<E> store(List<E> objets) { + // prepare data to send to service + List<Wikitty> wikitties = new ArrayList<Wikitty>(objets.size()); + for (E e : objets) { + Wikitty w = WikittyUtil.beanToWikitty(e); + wikitties.add(w); + } + + // call the service with Wikitty + UpdateResponse resp = wikittyService.store(wikitties); + + // update object + for (E e : objets) { + resp.update(e); + } + return objets; + } + + /** + * + * @param clazz + * @param id + * @param checkExtension if true check that Wikitty result has all extension + * declared in clazz + * @return + */ + public <E extends BusinessEntity> E restore(Class<E> clazz, String id, boolean checkExtension) { + E result = null; + HashSet extNames = null; + try { + Wikitty wikitty = wikittyService.restore(id); + if (checkExtension) { + extNames = new HashSet<String>(wikitty.getExtensionNames()); + } + result = WikittyUtil.newInstance(clazz, wikitty); + } catch (Exception eee) { + throw new WikittyException(eee); + } + if (checkExtension) { + // WikittyUtil.newInstance instanciate only BusinessEntityWikittyImpl + BusinessEntityWikitty b = (BusinessEntityWikitty)result; + for (WikittyExtension ext : b.getStaticExtensions()) { + if (!extNames.contains(ext.getName())) { + // extension wanted by BusinessEntity (clazz) + // is not in wikitty, then wikitty is not good type + // for business + throw new WikittyException(String.format( + "Id '%s' don't have extension '%s' but only %s", + id, ext.getName(), extNames)); + } + } + } + return result; + } + /** + * + * @param clazz + * @param id + * @return + */ + public <E extends BusinessEntity> E restore(Class<E> clazz, String id) { + E result = restore(clazz, id, false); + return result; + } + + /** + * + * @param clazz + * @param id + * @param checkExtension if true check that Wikitty result has all extension + * @return + */ + public <E extends BusinessEntity> List<E> restore( + Class<E> clazz, List<String> id, boolean checkExtension) { + + List<Wikitty> wikitties = wikittyService.restore(id); + List<E> result = new ArrayList<E>(); + for (Wikitty w : wikitties) { + HashSet extNames = null; + if (checkExtension) { + extNames = new HashSet<String>(w.getExtensionNames()); + } + + E dto = WikittyUtil.newInstance(clazz, w); + if (checkExtension) { + // WikittyUtil.newInstance instanciate only BusinessEntityWikittyImpl + BusinessEntityWikitty b = (BusinessEntityWikitty) dto; + for (WikittyExtension ext : b.getStaticExtensions()) { + if (!extNames.contains(ext.getName())) { + // extension wanted by BusinessEntity (clazz) + // is not in wikitty, then wikitty is not good type + // for business + throw new WikittyException(String.format( + "Id '%s' don't have extension '%s' but only %s", + w.getId(), ext.getName(), extNames)); + } + } + } + result.add(dto); + } + return result; + } + + public <E extends BusinessEntity> List<E> restore(Class<E> clazz, List<String> id) { + List<E> result = restore(clazz, id, false); + return result; + } + + public void delete(String id) { + wikittyService.delete(id); + } + + public void delete(Collection<String> ids) { + wikittyService.delete(ids); + } + + public <E extends BusinessEntityWikitty> PagedResult<E> findAllByExample(E e, + int firstIndex, int endIndex, String ... fieldFacet ) { + + Criteria criteria = Search.query(e.getWikitty()).criteria() + .setFirstIndex(firstIndex).setEndIndex(endIndex) + .setFacetField(fieldFacet); + + PagedResult<Wikitty> pagedResult = wikittyService.findAllByCriteria(criteria); + // we can use autoconvert = true because search by example add automaticaly + // restriction on extension + PagedResult<E> result = (PagedResult<E>)pagedResult.cast(e.getClass(), true); + return result; + } + + public <E extends BusinessEntityWikitty> E findByExample(E e) { + Criteria criteria = Search.query(e.getWikitty()).criteria(); + + Wikitty w = wikittyService.findByCriteria(criteria); + E result = (E)WikittyUtil.newInstance(e.getClass(), w); + return result; + } + + /** + * Search object that correspond to criteria and that have all extension + * needed by BusinessEntity (clazz). + * @param clazz + * @param criteria + * @return + */ + public <E extends BusinessEntity> PagedResult<E> findAllByCriteria( + Class<E> clazz, Criteria criteria) { + + // newInstance only return BusinessEntityWikittyImpl + BusinessEntityWikitty sample = + (BusinessEntityWikitty)WikittyUtil.newInstance(clazz); + + Wikitty wikitty = sample.getWikitty(); + Collection<String> extensions = wikitty.getExtensionNames(); + Search search = Search.query(criteria); + search = search.contains(Element.ELT_EXTENSION, extensions); + + Criteria serviceCriteria = search.criteria(criteria.getName()); + serviceCriteria.setFirstIndex(criteria.getFirstIndex()); + serviceCriteria.setEndIndex(criteria.getEndIndex()); + PagedResult<Wikitty> pagedResult = wikittyService.findAllByCriteria(serviceCriteria); + + // we can cast with autoconvert true because we have add restriction + // on extension + PagedResult<E> result = (PagedResult<E>)pagedResult.cast(sample.getClass(), true); + return result; + } + + public <E extends BusinessEntity> E findByCriteria(Class<E> clazz, Criteria criteria) { + BusinessEntityWikitty sample = + (BusinessEntityWikitty)WikittyUtil.newInstance(clazz); + + Wikitty wikitty = sample.getWikitty(); + Collection<String> extensions = wikitty.getExtensionNames(); + Search search = Search.query(criteria); + search = search.contains(Element.ELT_EXTENSION, extensions); + + criteria = search.criteria(criteria.getName()); + + Wikitty w = wikittyService.findByCriteria(criteria); + E result = WikittyUtil.newInstance(clazz, w); + return result; + } + + public void addLabel(String wikittyId, String label) { + wikittyService.addLabel(wikittyId, label); + } + + public PagedResult<Wikitty> findAllByLabel(String label, int firstIndex, int endIndex) { + PagedResult<Wikitty> result = wikittyService.findAllByLabel( + label, firstIndex, endIndex); + return result; + } + + public Wikitty findByLabel(String label) { + Wikitty result = wikittyService.findByLabel(label); + return result; + } + + public Set<String> findAllAppliedLabels(String wikittyId) { + Set<String> result = wikittyService.findAllAppliedLabels(wikittyId); + return result; + } + + public Tree restoreTree(String wikittyId) { + Tree result = wikittyService.restoreTree(wikittyId); + return result; + } + + public <E extends BusinessEntity> Map<E, Integer> restoreChildren(Class<E> clazz, String wikittyId) { + Map<TreeNode, Integer> result = wikittyService.restoreChildren(wikittyId); + if(result == null) { + return null; + } + + Map<E, Integer> convertedResult = new LinkedHashMap<E, Integer>(); + Set<Entry<TreeNode, Integer>> entries = result.entrySet(); + for (Entry<TreeNode, Integer> entry : entries) { + + TreeNode node = entry.getKey(); + String nodeId = node.getWikittyId(); + + E businessEntity = null; + HashSet extNames = null; + try { + Wikitty wikitty = wikittyService.restore(nodeId); + extNames = new HashSet<String>(wikitty.getExtensionNames()); + businessEntity = WikittyUtil.newInstance(clazz, wikitty); + } catch (Exception eee) { + throw new WikittyException(eee); + } + + // WikittyUtil.newInstance instanciate only BusinessEntityWikittyImpl + BusinessEntityWikitty businessEntityImpl = (BusinessEntityWikitty) businessEntity; + Collection<WikittyExtension> staticExtensions = businessEntityImpl.getStaticExtensions(); + + boolean goodType = true; + for (Iterator<WikittyExtension> iterator = staticExtensions.iterator(); iterator.hasNext() && goodType;) { + WikittyExtension ext = iterator.next(); + if (!extNames.contains(ext.getName())) { + // extension wanted by BusinessEntity (clazz) + // is not in wikitty, then wikitty is not good type + // for business + goodType = false; + } + } + + if(goodType) { + Integer nodeCount = entry.getValue(); + convertedResult.put(businessEntity, nodeCount); + } + } + return convertedResult; + } + + public Wikitty restoreVersion(String wikittyId, String version) { + Wikitty result = wikittyService.restoreVersion(wikittyId, version); + return result; + } + + public void syncImportFromXml(String xml) { + wikittyService.syncImportFromXml(xml); + } + + public void syncImportFromUri(String uri) { + wikittyService.syncImportFromUri(uri); + } + + /** + * + * @param uri + * @return job id + */ + public String asyncImportFromUri(String uri) { + String result = wikittyService.asyncImportFromUri(uri); + return result; + } + + /** + * + * @param e + * @return job id + */ + public <E extends BusinessEntityWikitty> String asyncExportAllByExample(E e) { + Criteria criteria = Search.query(e.getWikitty()).criteria(); + String result = wikittyService.asyncExportAllByCriteria(criteria); + return result; + } + + /** + * + * @param e + * @return xml string + */ + public <E extends BusinessEntityWikitty> String syncExportAllByExample(E e) { + Criteria criteria = Search.query(e.getWikitty()).criteria(); + String result = wikittyService.syncExportAllByCriteria(criteria); + return result; + } + + /** + * + * @param criteria + * @return job id + */ + public String asyncExportAllByCriteria(Criteria criteria) { + String result = wikittyService.asyncExportAllByCriteria(criteria); + return result; + } + + /** + * + * @param criteria + * @return xml string + */ + public String syncExportAllByCriteria(Criteria criteria) { + String result = wikittyService.syncExportAllByCriteria(criteria); + return result; + } + + /** + * give the job state + * @param jobId + * @return + */ + public JobState infoJob(String jobId) { + JobState result = wikittyService.infoJob(jobId); + return result; + } + + /** + * cancel job you must call freeJobResource + * @param jobId + */ + public void cancelJob(String jobId) { + wikittyService.cancelJob(jobId); + } + + /** + * This method must be call when your job is done and you have result, or + * when you call cancelJob + * @param jobId + */ + public void freeJobResource(String jobId) { + wikittyService.freeJobResource(jobId); + } + + public void changeDataDir(String newDataDir, String oldDataDir) { + wikittyService.changeDataDir(newDataDir, oldDataDir); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngin.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngin.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngin.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,81 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * WikittySearchEngin is used to abstract search engin used in WikittyService. + * + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface WikittySearchEngin { + + /** + * Remove all data in index, no call to commit needed. This method commit + * automaticaly. + */ + public void clear(); + + /** + * Prepare list of command needed to update indexation data. If command + * creation is impossible this method must throw an Exception + * @param wikitties + * @return + */ + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties); + + /** + * Commit all modification command passed in argument + * @param wikittyIndexationCommandList + * @return information usefull for client side update data + */ + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyIndexationCommandList); + + /** + * Delete all object with id argument. If id is not valid or don't exist + * throw an exception + * @param idList + * @return + */ + public List<Command> delete(WikittyTransaction transaction, + List<String> idList) throws WikittyException; + + public PagedResult<String> findAllByCriteria(Criteria criteria); + + /** + * Find all children ids with count for a node wikitty. + * @param w + * @return + */ + public Map<String, Integer> findAllChildren(Wikitty w); + + /** + * Command update + */ + static public interface Command {} +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngine.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngine.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittySearchEngine.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,89 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * WikittySearchEngine is used to abstract search engin used in WikittyService. + * + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface WikittySearchEngine { + + /** + * Remove all data in index, no call to commit needed. This method commit + * automaticaly. + */ + public void clear(); + + /** + * Changes the data directory + * @param newDataDir the new data directory path + * @param oldDataDir the old data directory path. + * If null, the data in the old directory will not be copied. + */ + public void changeDataDir(String newDataDir, String oldDataDir); + + /** + * Prepare list of command needed to update indexation data. If command + * creation is impossible this method must throw an Exception + * @param wikitties + * @return + */ + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties); + + /** + * Commit all modification command passed in argument + * @param wikittyIndexationCommandList + * @return information usefull for client side update data + */ + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyIndexationCommandList); + + /** + * Delete all object with id argument. If id is not valid or don't exist + * throw an exception + * @param idList + * @return + */ + public List<Command> delete(WikittyTransaction transaction, + List<String> idList) throws WikittyException; + + public PagedResult<String> findAllByCriteria(Criteria criteria); + + /** + * Find all children ids with count for a node wikitty. + * @param w + * @return + */ + public Map<String, Integer> findAllChildren(Wikitty w); + + /** + * Command update + */ + static public interface Command {} +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyService.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyService.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyService.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,275 @@ +/* *##% + * Copyright (c) 2009 Sharengo, Guillaume Dufrene, Benjamin POUSSIN. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import javax.swing.tree.TreeNode; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface WikittyService { + + /** + * Use {@link Criteria.ALL_ELEMENTS} + */ + @Deprecated + public static final int ALL_ELEMENTS = -1; + + /* + * Storage + */ + + /** + * Manage Update and creation. + * + * @param wikitty contains an id all the time. + */ + UpdateResponse store(Wikitty wikitty); + + /** + * Manage Update and creation. + * + * @param wikitties list of wikitty to be persisted + */ + UpdateResponse store(Collection<Wikitty> wikitties); + + /** + * Manage Update and creation. + * + * @param wikitties list of wikitty to be persisted + * @param disableAutoVersionIncrement boolean to disable version increment + * on saved wikitty + */ + UpdateResponse store(Collection<Wikitty> wikitties, + boolean disableAutoVersionIncrement); + + /** + * Return all extension id (ex: "extName[version])") + * @return + */ + List<String> getAllExtensionIds(); + + /** + * Return all extensions (ex: "extName[version])") + * @param lastVersion if true, returns only the last version of each extension + * @return + */ + List<WikittyExtension> getAllExtensions(boolean lastVersion); + + /** + * Manage Update and creation. + * + * @param exts list of wikitty extension to be persisted + */ + UpdateResponse storeExtension(Collection<WikittyExtension> exts); + + /** + * + * @param id + * @return the corresponding object, exception if no such object found. + */ + public WikittyExtension restoreExtension(String id); + + /** + * + * @param id object id to restore + * @return the corresponding object, or null if object doesn't exist or is + * deleted + */ + Wikitty restore( String id ); + + /** + * + * @param id list of wikitty ids to restore + * @return list of corresponding wikitty, if one id is not valid (no object + * or deleted) this id is skip and result list have less elements than + * collection argument + */ + List<Wikitty> restore( List<String> id ); + + /** + * delete object if id exists + * @param id object's id to remove + */ + void delete(String id); + + /** + * delete all object if id exists + * @param ids object's ids to remove + */ + void delete(Collection<String> ids); + + /** + * + * @param criteria + * @return + */ + public PagedResult<Wikitty> findAllByCriteria(Criteria criteria); + + /** + * Fist lonely (or first one) wikitty object that match criteria, if no wikitty found return null + * @param criteria + * @return + */ + public Wikitty findByCriteria(Criteria criteria); + + /* + * Labelisation + */ + + /** + * add new lable to the wikitty object + * @param wikittyId id of wikitty object to add label + * @param label label to add + */ + void addLabel(String wikittyId, String label); + + /** + * + * @param label + * @return + */ + PagedResult<Wikitty> findAllByLabel(String label, int firstIndex, int endIndex); + + /** + * + * @param label + * @return + */ + Wikitty findByLabel(String label); + + /** + * retrieve all labels applied on a wikitty object + * @param wikittyId + * @return + */ + Set<String> findAllAppliedLabels(String wikittyId); + + + /* + * Classification + * Most of classification purpose is handle by extension mechanisms + */ + + /** + * Retrieve all wikitties children (recursively) of an other one + * Wikitty reference by wikittyId MUST include the 'Node' extension + * + * @param wikittyId + * @return + */ + Tree restoreTree(String wikittyId); + + /** + * Retrieve all wikitties children with count (no recursively) of an other one + * Wikitty reference by wikittyId MUST include the 'Node' extension + * + * @param wikittyId + * @return + */ + Map<org.sharengo.wikitty.TreeNode, Integer> restoreChildren(String wikittyId); + + + /* + * history + */ + + /** + * + */ + Wikitty restoreVersion(String wikittyId, String version); + + /* + * Import / Export + */ + + + /** + * synchonous or not ? + * + * @param xml data to import + */ + void syncImportFromXml(String xml); + + /** + * + * @param uri + */ + void syncImportFromUri(String uri); + + /** + * + * @param uri + * @return a jobID + */ + String asyncImportFromUri(String uri); + + /** + * + * @param criteria + * @return + */ + String asyncExportAllByCriteria(Criteria criteria); + + /** + * + * @param criteria + * @return + */ + String syncExportAllByCriteria(Criteria criteria); + + /* + * Job Management + */ + + /** + * + * @param jobId + * @return + */ + JobState infoJob(String jobId); + + /** + * + * @param jobId + */ + void cancelJob(String jobId); + + /** + * delete job info and all resources associated to that job (files or other ...) + */ + void freeJobResource(String jobId); + + /** + * Changes the data directory + * @param newDataDir the new data directory path + * @param oldDataDir the old data directory path. + * If null, the data in the old directory will not be copied. + */ + public void changeDataDir(String newDataDir, String oldDataDir); + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyServiceInMemory.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyServiceInMemory.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyServiceInMemory.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,423 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.FieldType.TYPE; +import org.sharengo.wikitty.search.And; +import org.sharengo.wikitty.search.BinaryOperator; +import org.sharengo.wikitty.search.Element; +import org.sharengo.wikitty.search.Restriction; + +/** + * In memory implementation of WikittyService, currently used for test only + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceInMemory extends AbstractWikittyService { + + //FIXME InMemory implementation is not usable for production. Must be reviewed. + //FIXME The version increment must be done in 'prepare' method + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceInMemory.class); + + @Override + public List<WikittyExtension> getAllExtensions(boolean lastVersion) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + class WikittyStorageInMemory implements WikittyStorage { + protected Map<String, Wikitty> wikitties = new LinkedHashMap<String, Wikitty>(); + + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties, + boolean disableAutoVersionIncrement) throws WikittyException { + + List<Command> result = new ArrayList<Command>(wikitties.size()); + for (Wikitty w : wikitties) { + result.add(new CommandInMemory(w, true)); + } + return result; + } + + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyStorageCommandList) { + UpdateResponse result = new UpdateResponse(); + Date now = new Date(); + for (Command c : wikittyStorageCommandList) { + CommandInMemory cim = (CommandInMemory)c; + if (cim.toStore) { + cim.wikitty.version = WikittyUtil.incrementMajorRevision( + cim.wikitty.version); + cim.wikitty.fieldDirty.clear(); + result.addVersionUpdate(cim.wikitty.getId(), cim.wikitty.version); + } else { + cim.wikitty.setDeleteDate(now); + result.addDeletionDateUpdate(cim.wikitty.getId(), now); + } + wikitties.put(cim.wikitty.getId(), cim.wikitty); + } + return result; + } + + public boolean exists(String id) { + boolean result = wikitties.containsKey(id); + return result; + } + + public boolean isDeleted(String id) { + boolean result = false; + Wikitty w = wikitties.get(id); + if (w == null) { + throw new WikittyException(String.format("No wikitty with id '%s'", id)); + } else { + result = w.isDeleted(); + } + return result; + } + + public Wikitty restore(String id, String ... fqFieldName) throws WikittyException { + Wikitty result = wikitties.get(id); + if (result.isDeleted()) { + result = null; + } + if (result == null) { + throw new WikittyException(String.format("No wikitty with id '%s'", id)); + } + return result; + } + + public List<Wikitty> restore(Collection<String> ids, + String ... fqFieldName) throws WikittyException { + List<Wikitty> result = new ArrayList<Wikitty>(ids.size()); + for (String id : ids) { + Wikitty w = restore(id, fqFieldName); + result.add(w); + } + return result; + } + + public List<Command> delete(List<String> idList) throws WikittyException { + List<Command> result = new ArrayList<Command>(idList.size()); + for (String id : idList) { + Wikitty w = restore(id); + result.add(new CommandInMemory(w, false)); + } + return result; + } + + class CommandInMemory implements Command { + /** if true command is for storage, if false for deletion */ + boolean toStore; + Wikitty wikitty; + public CommandInMemory(Wikitty wikitties, boolean toStore) { + this.wikitty = wikitties; + this.toStore = toStore; + } + } + } + + class WikittyExtensionStorageInMemory implements WikittyExtensionStorage { + protected Map<String, WikittyExtension> extensions; + + public WikittyExtensionStorageInMemory() { + this.extensions = new HashMap<String, WikittyExtension>(); + } + + public List<Command> prepare(WikittyTransaction transaction, + Collection<WikittyExtension> extensions) throws WikittyException { + List<Command> result = new ArrayList<Command>(extensions.size()); + for (WikittyExtension ext : extensions) { + CommandInMemory command = new CommandInMemory(ext); + result.add(command); + } + return result; + } + + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> extensionStorageCommandList) { + for (Command c : extensionStorageCommandList) { + CommandInMemory cim = (CommandInMemory)c; + WikittyExtension ext = cim.ext; + extensions.put(ext.getId(), ext); + } + + // nothing to do in UpdateResponse + UpdateResponse result = new UpdateResponse(); + return result; + } + + public boolean exists(String id) { + boolean result = extensions.containsKey(id); + return result; + } + + public List<String> getAllExtensionIds() { + List<String> result = new ArrayList<String>(extensions.keySet()); + return result; + } + + @Override + public List<WikittyExtension> getAllExtensions(boolean lastVersion) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public WikittyExtension restore(String id) throws WikittyException { + WikittyExtension result = extensions.get(id); + if (result == null) { + throw new WikittyException(String.format("No extension with id '%s'", id)); + } + return result; + } + + public String getLastVersion(String extName) { + throw new UnsupportedOperationException("Not supported yet."); + } + + class CommandInMemory implements Command { + WikittyExtension ext; + public CommandInMemory(WikittyExtension ext) { + this.ext = ext; + } + } + } + + class WikittySearchEngineInMemory implements WikittySearchEngine { + + WikittyStorageInMemory wikittyStorage; + + public WikittySearchEngineInMemory(WikittyStorageInMemory wikittyStorage) { + this.wikittyStorage = wikittyStorage; + } + + public void clear() { + // do nothing + } + + @Override + public void changeDataDir(String newDataDir, String oldDataDir) { + //Do nothing + } + + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties) { + // do nothing + return new ArrayList<Command>(); + } + + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyIndexationCommandList) { + // do nothing + return new UpdateResponse(); + } + + public List<Command> delete(WikittyTransaction transaction, + List<String> idList) throws WikittyException { + // do nothing + return new ArrayList<Command>(); + } + + public boolean checkRestriction( Restriction restriction, Wikitty w ) { + if ( restriction instanceof BinaryOperator ) { + BinaryOperator binOp = (BinaryOperator) restriction; + + if ( binOp.getElement().equals(Element.ELT_EXTENSION) ) { + return w.hasExtension( (String) binOp.getValue() ); + } + + String fqfieldName = binOp.getElement().getName(); + Object o = w.getFqField( fqfieldName ); + FieldType t = w.getFieldType(fqfieldName); + Object value = t.getValidValue( binOp.getValue() ); + boolean checked = false; + switch( restriction.getName() ) { + case EQUALS: + checked = value.equals(o); + break; + case LESS: + checked = ((Comparable)o).compareTo( value ) < 0; + break; + case LESS_OR_EQUAL: + checked = ((Comparable)o).compareTo( value ) <= 0; + break; + case GREATER: + checked = ((Comparable)o).compareTo( value ) > 0; + break; + case GREATER_OR_EQUAL: + checked = ((Comparable)o).compareTo( value ) >= 0; + break; + case NOT_EQUALS: + checked = !value.equals(o); + break; + case ENDS_WITH: + if ( t.getType() != TYPE.STRING ) + throw new WikittyException("Can't search for contents that 'ends with' on attribute type different of String. " + + "Attribute " + fqfieldName + " is " + t.getType().name() ); + checked = ((String) o).endsWith( (String) value ); + break; + case STARTS_WITH: + if ( t.getType() != TYPE.STRING ) + throw new WikittyException("Can't search for contents that 'starts with' on attribute type different of String. " + + "Attribute " + fqfieldName + " is " + t.getType().name() ); + checked = ((String) o).startsWith( (String) value ); + break; + } + return checked; + } else if ( restriction instanceof And ) { + And and = (And) restriction; + for ( Restriction sub : and.getRestrictions() ) { + if ( !checkRestriction(sub, w) ) return false; + } + return true; + } else { + throw new UnsupportedOperationException( restriction.getName() + " Search Not yet implemented"); + } + } + + public PagedResult<String> findAllByCriteria( + Criteria criteria) { + // throw new UnsupportedOperationException("Not supported yet."); + + int firstIndex = criteria.getFirstIndex(); + int endIndex = criteria.getEndIndex(); + + List<String> ids = new LinkedList<String>(); + int currentIndex = 0; + + for( Entry<String, Wikitty> entry : wikittyStorage.wikitties.entrySet() ) { + Wikitty w = entry.getValue(); + String id = entry.getKey(); + Restriction dto = criteria.getRestriction(); + + if ( checkRestriction(dto, w) ) { + currentIndex++; + if ( currentIndex > firstIndex ) ids.add( id ); + if ( endIndex >= 0 && currentIndex >= endIndex ) break; + } + + } + return new PagedResult<String>(firstIndex, endIndex, criteria.getRestriction().toString(), null, ids ); + } + + public PagedResult<String> findAllByCriteria( + Criteria criteria, int firstIndex, int endIndex, String... fieldFacet) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public PagedResult<String> findAllByCriteria( + Criteria criteria, int firstIndex, int endIndex, Criteria... criteriaFacet) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Map<String, Integer> findAllChildren(Wikitty w) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + + /** + * if persitenceFile is not null, serialize all data to disk during store + * operation and the file is reloaded during init + */ + protected File persitenceFile = null; + + protected WikittyStorage wikittyStorage; + protected WikittyExtensionStorage extensionStorage; + protected WikittySearchEngine searchEngine; + + public WikittyServiceInMemory() { + extensionStorage = new WikittyExtensionStorageInMemory(); + wikittyStorage = new WikittyStorageInMemory(); + searchEngine = new WikittySearchEngineInMemory((WikittyStorageInMemory)wikittyStorage); + } + + public WikittyServiceInMemory(File persitenceFile) { + this(); + this.persitenceFile = persitenceFile; + if (persitenceFile != null && persitenceFile.exists()) { + try { + ObjectInputStream in = new ObjectInputStream(new FileInputStream( + persitenceFile)); + ((WikittyExtensionStorageInMemory)extensionStorage).extensions = (Map) in.readObject(); + ((WikittyStorageInMemory)wikittyStorage).wikitties = (Map) in.readObject(); + in.close(); + } catch (Exception eee) { + log.error("Can't read data file " + persitenceFile, eee); + } + } + } + + @Override + protected WikittyStorage getWikittyStorage() { + return wikittyStorage; + } + + @Override + protected WikittyExtensionStorage getExtensionStorage() { + return extensionStorage; + } + + @Override + protected WikittySearchEngine getSearchEngine() { + return searchEngine; + } + + @Override + protected void finalize() throws Throwable { + saveToPersistenceFile(); + + super.finalize(); + } + + public void saveToPersistenceFile() { + if (persitenceFile != null) { + try { + ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream( + persitenceFile)); + out.writeObject(((WikittyExtensionStorageInMemory)extensionStorage).extensions); + out.writeObject(((WikittyStorageInMemory)wikittyStorage).wikitties); + out.close(); + } catch (IOException eee) { + log.error("Can't write data file " + persitenceFile, eee); + } + } + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyStorage.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyStorage.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyStorage.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,96 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + +import java.util.Collection; +import java.util.List; + +/** + * WikittyStorage is used to abstract data and extension storage in WikittyService. + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface WikittyStorage { + + /** + * Prepare command's List needed to update the storage + * @param wikitties + * @param disableAutoVersionIncrement TODO + * @return + */ + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties, boolean disableAutoVersionIncrement) + throws WikittyException; + + /** + * Commit all modification command passed in argument + * @param wikittyStorageCommandList + * @return information usefull for client side update data + */ + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyStorageCommandList); + + /** + * Return true if id exists in storage + * @param id + * @return + */ + public boolean exists(String id); + + /** + * Return true if wikitty object with this id are marked deleted + * @param id + * @return + */ + public boolean isDeleted(String id); + + /** + * Restore one wikitty object, if wikitty not found an exception is throw + * @param id wikitty id + * @return + */ + public Wikitty restore(String id, String ... fqFieldName) throws WikittyException; + + /** + * Restore list of wikitty object, if wikitty not found an exception is throw + * @param id list of wikitty id + * @param fqFieldName list of field that must be loaded, other fields + * can be not loaded + * @return + */ + public List<Wikitty> restore(Collection<String> id, + String ... fqFieldName) throws WikittyException; + + /** + * Delete all object with id argument. If id is not valid or don't exist + * throw an exception + * @param idList + * @return + */ + public List<Command> delete(List<String> idList) throws WikittyException; + + /** + * Command update + */ + static public interface Command {} + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyTransaction.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyTransaction.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyTransaction.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,25 @@ +package org.sharengo.wikitty; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represent a transaction, to store some information during execution. + */ +public class WikittyTransaction { + + protected Map<Object, Object> tagValues; + + public WikittyTransaction() { + tagValues = new HashMap<Object, Object>(); + } + + public Object getTagValue(Object tag) { + return tagValues.get(tag); + } + + public void setTagValue(Object tag, Object value) { + tagValues.put(tag, value); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyUtil.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyUtil.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/WikittyUtil.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,755 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty; + + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.UUID; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * Util static method for wikitty + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyUtil { + + public static final String DEFAULT_VERSION = "0.0"; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyUtil.class); + + /** used to format date for solr*/ + protected static TimeZone CANONICAL_TZ = TimeZone.getTimeZone("UTC"); + protected static final Locale CANONICAL_LOCALE = Locale.US; + + static final public SimpleDateFormat solrDateFormat = new SolrDateFormat(); + + public static class SolrDateFormat extends SimpleDateFormat { + public SolrDateFormat() { + super("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", CANONICAL_LOCALE); + setTimeZone(CANONICAL_TZ); + } + } + + /** All date format parser used to convert string to date */ + static final protected DateFormat[] parserDateFormats = new DateFormat[]{ + solrDateFormat, + DateFormat.getInstance (), + // TODO poussin 20090813: add other date syntax + }; + + // TODO poussin 20090902 use spring configuration to add mapping in this variable + /** contains mapping between interface and concret class that must be used */ + static public Map<Class, Class> interfaceToClass = new HashMap<Class, Class>(); + + /** + * Field pattern parser + * <li> group 1: type (string) + * <li> group 2: name (string) + * <li> group 3: lower bound (number) can be null + * <li> group 4: upper bound (number) can be null, mutualy exclusif with group 5 + * <li> group 5: upper bound (n or *) can be null + * <li> group 6: unique can be null + * <li> group 7: not null can be null + * <li> group 8: all tag/value (toto=titi tutu=tata;lala) no space allowed in tag or value + */ + static protected Pattern fieldPattern = Pattern.compile( + "\\s*(\\w+)\\s+(\\w+)(?:\\s*\\[(\\d+)-(?:(\\d+)|([\\*n]))\\])?(?:\\s+(unique))?(?:\\s+(not null))?((?:\\s+\\w+=(\\w|;)+)*)"); + + /** + * parse FieldType definition and return field name. All field information + * are stored in fieldType object passed in argument + * @param def string field definition + * @param fieldType object used to put parsed information + * @return field name parsed in definition + */ + static public String parseField(String def, FieldType fieldType) { + Matcher match = fieldPattern.matcher(def); + if (match.matches()) { + fieldType.type = FieldType.TYPE.parse(match.group(1)); + String name = match.group(2); + String lower = match.group(3); + if (lower != null) { + fieldType.lowerBound = Integer.parseInt(lower); + } + + String upper = match.group(4); + if (upper != null) { + fieldType.upperBound = Integer.parseInt(upper); + } + String noupper = match.group(5); + if (noupper != null) { + fieldType.upperBound = FieldType.NOLIMIT; + } + String uniqueString = match.group(6); + fieldType.unique = uniqueString != null; + + String notNullString = match.group(7); + fieldType.notNull = notNullString != null; + + String tagValues = match.group(8); + if (tagValues != null) { + String[] tagValuesTab = tagValues.trim().split("\\s"); + for (String tagValue : tagValuesTab) { + String[] tagValueTab = tagValue.trim().split("="); + if (tagValueTab.length != 2) { + log.warn(String.format( + "Illegal tag/value declaration '%s' in '%s'", + tagValue, def)); + } else { + String tag = tagValueTab[0]; + String value = tagValueTab[1]; + fieldType.addTagValue(tag, value); + } + } + } + + return name; + } else { + throw new WikittyException(String.format("Bad FieldType definition '%s'", def)); + } + } + + /** + * Create map from string representation + * + * ex: "String name", "Wikitty children[0-*]" + * + * @param definitions + * @return + */ + public static LinkedHashMap<String, FieldType> buildFieldMapExtension(String... definitions) { + LinkedHashMap<String, FieldType> result = new LinkedHashMap<String, FieldType>(); + for(String def : definitions) { + FieldType fieldType = new FieldType(); + String name = WikittyUtil.parseField(def, fieldType); + log.debug("parse " + def + " => " + fieldType.toDefinition(name) ); + result.put(name, fieldType); + } + return result; + } + + /** + * if version if null return 0 else version + * @param version + * @return + */ + public static String normalizeVersion(String version) { + if (version == null || "".equals(version)) { + version = "0"; + } + return version; + } + + /** + * return true if v1 and v2 are egals + * 1.2.0 et 1.2 ne sont pas egaux + */ + public static boolean versionEquals(String v1, String v2) { + if ( v1 == null || v2 == null ) return false; + return normalizeVersion(v1).equals(normalizeVersion(v2)); + } + + /** + * return true if v1 greater than v2 + * @param v1 + * @param v2 + * @return + */ + public static boolean versionGreaterThan(String v1, String v2) { + if ( v1 != null && v2 == null ) return true; + if ( v1 == null ) return false; + String[] v1s = normalizeVersion(v1).split("\\."); + String[] v2s = normalizeVersion(v2).split("\\."); + int minlen = Math.min(v1s.length, v2s.length); + for (int i = 0; i < minlen; i++) { + if (!v1s[i].equals(v2s[i])) + return Integer.parseInt(v1s[i]) > Integer.parseInt(v2s[i]); + } + // si on est ici c que tout les nombres sont v1[i] = v2[i] + return v1s.length > v2s.length; + } + + /** + * increment minor version. + * @param version version as 3.1 where 1 is minor and 3 major + * @return incremented minor number (3.1 -> 3.2) + */ + static public String incrementMinorRevision(String v) { + String result; + + if (v == null || "".equals(v)) { + result = "0.1"; + } else { + v = v.trim(); + String[] mm = v.split("\\."); + if (mm.length == 1) { + result = v + ".1"; + } else { + int i = Integer.parseInt(mm[1]) + 1; + result = mm[0] + "." + i; + } + } + return result; + } + + /** + * increment minor version. + * @param version version as 3.2 where 2 is minor and 3 major + * @return incremented majar number and reset minor number (3.2 -> 4.0) + */ + static public String incrementMajorRevision(String v) { + String result; + + if (v == null || "".equals(v)) { + result = "1.0"; + } else { + v = v.trim(); + String[] mm = v.split("\\."); + int i = Integer.parseInt(mm[0]) + 1; + result = i + ".0"; + } + return result; + } + +// /** +// * +// * @param value null and empty string are casted to '0' int value. +// * @throws WikittyException on NumberFormatException or if value object can't be casted to int. +// */ +// static public int toInt(Object value) throws WikittyException { +// int result = 0; +// if (value == null || value.equals("") ) { +// result = 0; // default to 0 +// } else if (value instanceof Number) { +// result = ((Number) value).intValue(); +// } else { +// // try to convert to int +// try { +// result = Integer.parseInt(value.toString()); +// } catch (NumberFormatException eee) { +// throw new WikittyException(String.format( +// "Can't convert value '%s' to int", getClass(value)), eee); +// } +// } +// return result; +// } +// +// static public float toFloat(Object value) throws WikittyException { +// float result = 0; +// if (value == null) { +// result = 0; // default to 0 +// } else if (value instanceof Number) { +// result = ((Number) value).floatValue(); +// } else { +// // try to convert to float +// try { +// result = Float.parseFloat(value.toString()); +// } catch (NumberFormatException eee) { +// throw new WikittyException(String.format( +// "Can't convert value '%s' to float", getClass(value)), eee); +// } +// } +// return result; +// } + + /** + * + * @param value null and empty string are casted to '0' value. + * @throws WikittyException on NumberFormatException or if value object + * can't be casted to number. + */ + static public BigDecimal toBigDecimal(Object value) { + BigDecimal result = null; + if (value == null) { + result = new BigDecimal(0); // default to 0 + } else if (value instanceof BigDecimal) { + result = (BigDecimal)value; + } else { + try { + result = new BigDecimal(value.toString()); + } catch (NumberFormatException eee) { + throw new WikittyException(String.format( + "Can't convert value '%s' to numeric", getClass(value)), eee); + } + } + return result; + } + + /** + * Convert object to boolean: + * - null => false + * - 0 => false + * - numeric => true + * - object.toString() == false => false + * - other => true + * + * @param value + * @return + */ + static public boolean toBoolean(Object value) { + boolean result = false; + if (value != null) { + if (value instanceof Boolean) { + result = (Boolean) value; + } else if (value instanceof Number) { + result = ! ((Number)value).equals(0); + }else { + // try to convert to Boolean + result = ! "false".equalsIgnoreCase(value.toString()); + } + } + return result; + } + + static public String toString(Object value) { + String result = null; + if (value != null) { + if (value instanceof String) { + result = (String) value; + } else if (value instanceof Wikitty) { + result = ((Wikitty) value).getId(); + } else if (value instanceof BusinessEntity) { + result = ((BusinessEntity) value).getWikittyId(); + } else if (value instanceof Date) { + result = solrDateFormat.format((Date)value); + } else { + // try to convert to String + result = value.toString(); + } + } + return result; + } + + static public Date toDate(Object value) { + Date result = null; + if (value != null) { + if (value instanceof Date) { + result = (Date) value; + } else { + // try to convert to Date + try { + result = solrDateFormat.parse(value.toString()); + } catch (ParseException eee) { + log.debug("Can't parse date, i try with next parser", eee); + } + + if (result == null) { + throw new WikittyException(String.format( + "Can't convert value '%s' of type '%s' to Date", + value ,getClass(value))); + } + } + } + return result; + } + + /** + * return wikitty id and not wikitty objet because this method can be call + * on server or client side and it's better to keep conversion between id + * and objet to the caller + * @param value + * @return id of wikitty object or null + * @throws org.sharengo.wikitty.WikittyException + */ + static public String toWikitty(Object value) { + String result = null; + if (value != null) { + if (value instanceof String) { + result = (String) value; + } else if (value instanceof Wikitty) { + result = ((Wikitty)value).getId(); + } else if (value instanceof BusinessEntity) { + result = ((BusinessEntity)value).getWikittyId(); + } else { + // try to convert to String + result = value.toString(); + } + } + return result; + } + + /** + * + * @param <E> + * @param clazz + * @return unmodifiable list + */ + static public <E> List<E> toList(Object value, Class<E> clazz) { + try { + List<E> result = (List<E>) value; + if (result != null) { + result = Collections.unmodifiableList(result); + } + return result; + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't convert value '%s' to list", getClass(value)), eee); + } + } + + /** + * Convert object o for indexation + * @param field field description + * @param o field value + * @return solr representation + */ + static public String toString(FieldType field, Object o) { + String result = null; + switch (field.getType()) { + case DATE: + // Date date = (Date)o; + result = (o instanceof String) ? (String) o : WikittyUtil.solrDateFormat.format( (Date)o ); + break; + default: + result = WikittyUtil.toString(o); + break; + } + return result; + } + + /** + * convert string field representation to correct value type + * @param field field description + * @param s string value + * @return object in type of field + */ + static public Object fromString(FieldType field, String s) { + Object result = null; + switch (field.getType()) { + case BOOLEAN: + result = WikittyUtil.toBoolean(s); + break; + case DATE: + result = WikittyUtil.toDate(s); + break; + case NUMERIC: + result = WikittyUtil.toBigDecimal(s); + break; + default: + result = s; + break; + } + return result; + } + + + /** + * return class of argument, if argument is null, return null + * @param value + * @return class of value or null + */ + static public Class getClass(Object value) { + Class result = null; + if (value != null) { + result = value.getClass(); + } + return result; + } + + /** + * Create new instance of WikittyDto without Wikitty object + * passed in argument. If arguement is Interface try to add 'Impl' to find + * instanciable class. + * <p> + * clazz parameter must be child of WikittyDto or business interface + * @param clazz class of the new instance + * @return + */ + static public <E extends BusinessEntity> E newInstance(Class<E> clazz) { + try { + Class clazzInstanciable = clazz; + if (clazzInstanciable.isInterface()) { + log.debug(String.format( + "Argument '%s' is interface looking for implementation", + clazzInstanciable.getName())); + // looking for implementation of this interface + if (interfaceToClass.containsKey(clazz)) { + clazzInstanciable = interfaceToClass.get(clazz); + } else { + // default use xxxImpl.class + clazzInstanciable = clazz.forName(clazz.getName() + "Impl"); + } + } + + if (!BusinessEntityWikitty.class.isAssignableFrom(clazzInstanciable)) { + throw new WikittyException(String.format( + "Your class '%s' don't extends WikittyDto", clazz.getName())); + } + + E result = (E) clazzInstanciable.newInstance(); + return result; + + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + /** + * Create new instance of WikittyDto with Wikitty object + * passed in argument. If arguement is Interface try to add 'Impl' to find + * instanciable class. + * <p> + * clazz parameter must be child of WikittyDto or business interface + * @param clazz class of the new instance + * @param w wikitty object to use internaly for in new instance + * @return + * @deprecated You should use <name>Impl.toBean() and new <name>Impl(Bean) + */ + // E extends BeanDto to permit business interface as parameter + @Deprecated + static public <E extends BusinessEntity> E newInstance(Class<E> clazz, Wikitty w) { + try { + Class clazzInstanciable = clazz; + if (clazzInstanciable.isInterface()) { + log.debug(String.format( + "Argument '%s' is interface looking for implementation", + clazzInstanciable.getName())); + // looking for implementation of this interface + if (interfaceToClass.containsKey(clazz)) { + clazzInstanciable = interfaceToClass.get(clazz); + } else { + // default use xxxImpl.class + clazzInstanciable = clazz.forName(clazz.getName() + "Impl"); + } + } + + if (!BusinessEntityWikitty.class.isAssignableFrom(clazzInstanciable)) { + throw new WikittyException(String.format( + "Your class '%s' don't extends WikittyDto", clazz.getName())); + } + E result = null; + if (w != null) { + try { + // try to find constructor with wikitty argument + Constructor cons = clazzInstanciable.getConstructor(Wikitty.class); + result = (E) cons.newInstance(w); + } catch (NoSuchMethodException noerror) { + log.debug(String.format( + "Can't find constructor with wikitty arguement in '%s'," + + "we try with setWikitty method", + clazzInstanciable.getName()), noerror); + result = (E) clazzInstanciable.newInstance(); + ((BusinessEntityWikitty)result).setWikitty(w); + } + } + + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + + + /** + * Try to cast obj to class passed in arguement + * @param obj object to cast + * @param clazz new type of object + * @return the same object but casted to class wanted, except for primitif + * where is new object if obj BigDecimal + */ + public static <E> E cast( Object obj, Class<E> clazz) { + E result = null; + if ( obj != null ) { + if (clazz.isAssignableFrom(obj.getClass())) { + result = clazz.cast(obj); + } else if (obj instanceof BigDecimal) { + BigDecimal bd = (BigDecimal) obj; + if (clazz == int.class || clazz == Integer.class) { + result = clazz.cast(bd.intValue()); + } else if (clazz == float.class || clazz == Float.class) { + result = clazz.cast(bd.floatValue()); + } + } + if (result == null) { + throw new WikittyException("Unable to cast from '" + obj.getClass().getName() + "' to " + clazz.getName()); + } + } + return result; + } + + public static Wikitty beanToWikitty(BusinessEntity bean) { + Wikitty result; + if (bean instanceof BusinessEntityWikitty) { + BusinessEntityWikitty b = (BusinessEntityWikitty) bean; + result = b.getWikitty(); + } else if (bean instanceof BusinessEntityBean) { + BusinessEntityBean b = (BusinessEntityBean) bean; + result = WikittyUtil.beanToWikitty(b); + } else { + throw new IllegalArgumentException(String.format( + "This BusinessEntity implementation is not supported: %s", + bean.getClass().getName())); + } + return result; + } + + public static Wikitty beanToWikitty(BusinessEntityBean bean) { + try { + // TODO poussin 20090910 for now, we force version change, but it's better if we modify version in bean we field is set + Wikitty result = new Wikitty(bean.getWikittyId()); + // prevent BusinessEntity with null id (during store call for creation) + bean.id = result.id; + result.version = bean.getWikittyVersion(); + + // add execution defined extension in wikitty + for(String extName : bean.getExtensionNames()) { + for (String fieldName : bean.getExtensionFields(extName)){ + Object value = bean.getField(extName, fieldName); + result.setField(extName, fieldName, value); + } + } + + // add development time defined extension in wikitty + Field[] fields = bean.getClass().getFields(); + for (Field field : fields) { + Object value = field.get(bean); + String fqfieldName = field.getName(); + // fieldName use $ as separator between extension name and field name + fqfieldName = fqfieldName.replace('$', '.'); + result.setFqField(fqfieldName, value); + } + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + public static <E extends BusinessEntityBean, F extends BusinessEntityWikitty> + E wikittyToBean(Class<E> clazz, F dto) { + E result = wikittyToBean(clazz, dto.getWikitty()); + return result; + } + /** + * Convert WikittyDto (dto that encapsulate Wikitty) to BeanDto (dto + * without internaly wikitty) + * + * @param clazz target object clazz + * @param w source object + * @return + */ + public static <E extends BusinessEntityBean> E wikittyToBean( + Class<E> clazz, Wikitty w) { + try { + E result = clazz.newInstance(); + result.id = w.id; + result.version = w.version; + result.extensions = new LinkedHashMap<String, WikittyExtension>( + w.extensions); + + Field[] fields = clazz.getFields(); + Map<String, Field> allFields = new HashMap<String, Field>(); + for (Field field : fields) { + allFields.put(field.getName(), field); + } + + for (String extName : result.extensions.keySet()) { + WikittyExtension ext = result.extensions.get(extName); + for (String fieldName : ext.getFieldNames()) { + String key = extName + "$" + fieldName; + Field field = allFields.get(key); + if (field != null) { + Class type = field.getType(); + if (Integer.TYPE.isAssignableFrom(type)) { + int value = w.getFieldAsInt(extName, fieldName); + field.setInt(result, value); + } else if (Boolean.TYPE.isAssignableFrom(type)) { + boolean value = w.getFieldAsBoolean(extName, fieldName); + field.setBoolean(result, value); + } else if (Date.class.isAssignableFrom(type)) { + Date value = w.getFieldAsDate(extName, fieldName); + field.set(result, value); + } else if (Double.TYPE.isAssignableFrom(type)) { + double value = w.getFieldAsDouble(extName, fieldName); + field.setDouble(result, value); + } else if (Float.TYPE.isAssignableFrom(type)) { + float value = w.getFieldAsFloat(extName, fieldName); + field.setFloat(result, value); + } else if (List.class.isAssignableFrom(type)) { + List value = w.getFieldAsList(extName, fieldName, clazz); + field.set(result, value); + } else if (Long.TYPE.isAssignableFrom(type)) { + long value = w.getFieldAsLong(extName, fieldName); + field.setLong(result, value); + } else if (Set.class.isAssignableFrom(type)) { + Set value = w.getFieldAsSet(extName, fieldName, clazz); + field.set(result, value); + } else if (String.class.isAssignableFrom(type)) { + String value = w.getFieldAsString(extName, fieldName); + field.set(result, value); + } else { + throw new WikittyException(String.format( + "Can't convert field for '%s' because" + + " unkonw field type '%s'", + clazz, field)); + } + } else { + Object value = w.getFieldAsObject(extName, fieldName); + result.setField(extName, fieldName, value); + } + } + } + + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + // private static BASE64Encoder enc = new BASE64Encoder(); + public static String genUID() { + return UUID.randomUUID().toString(); + /* we can gain 10 chars per ID on applying a base64 on the UID. + long mostSignificant = uid.getMostSignificantBits(); + long leastSignificant = uid.getLeastSignificantBits(); + long current = mostSignificant; + byte[] b = new byte[16]; + for ( int i = 0; i < 16; i++ ) { + b[i] = (byte) (current & 0xff); + current = current >> 8; + if ( i == 7 ) current = leastSignificant; + } + return enc.encode(b); + */ + } +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/And.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/And.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/And.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,93 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; +import java.util.List; + +// End of user code for import + +/** + * <!-- Start of user code for And --> + * + * <p> + * And operator is used to build conjunctive restriction for request on content. + * It take at least 2 args. <br> + * <br> + * For example, use: + * <ul> + * <li>RestrictionHelper.and( restriction1, restriction2 )</li> + * <li>RestrictionHelper.and( restriction1, restriction2, restriction3 )</li> + * <li>RestrictionHelper.and( + * my_JavaUtilList_Of_Restriction_Witch_Size_Is_Upper_Than2 )</li> + * </ul> + * </p> + * + * <!-- End of user code for And --> + */ +public class And extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected List<Restriction> restrictions; + + /** + * Default constructor + */ + public And() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param restrictions + */ + public And(List<Restriction> restrictions) { + this.restrictions = restrictions; + } + + /** + * Return restrictions + * + * @return + */ + public List<Restriction> getRestrictions() { + return restrictions; + } + + /** + * Set a value to parameter restrictions. + * + * @param restrictions + */ + public void setRestrictions(List<Restriction> restrictions) { + this.restrictions = restrictions; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof And)) { + return false; + } + + final And and = (And) other; + + if ((restrictions == null && and.getRestrictions() != null) + || (restrictions != null && !restrictions.equals(and + .getRestrictions()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/AssociatedRestriction.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/AssociatedRestriction.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/AssociatedRestriction.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,33 @@ +package org.sharengo.wikitty.search; + +public class AssociatedRestriction extends Restriction { + + private static final long serialVersionUID = 1L; + + private Restriction associatedRestriction; + private Restriction embededRestriction; + private Element element; + + public AssociatedRestriction(Restriction parentRestriction, Restriction embededRestriction, Element element) { + this.associatedRestriction = parentRestriction; + this.embededRestriction = embededRestriction; + this.name = RestrictionName.ASSOCIATED; + this.element = element; + } + + public Restriction getParentRestrictionDto() { + return associatedRestriction; + } + + public Element getElement() { + return element; + } + + public void setElement(Element element) { + this.element = element; + } + + public Restriction getRestriction() { + return embededRestriction; + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Between.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Between.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Between.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,133 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for Between --> + * + * <p> + * Between operator is used to build restriction containing "min < element + * < max" where element could be a Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.between( myElement , "15.5" , "22.5" ) + * </p> + * + * <!-- End of user code for Between --> + */ +public class Between extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected Element element; + protected String min; + protected String max; + + /** + * Default constructor + */ + public Between() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param element + * @param min + * @param max + */ + public Between(Element element, String min, String max) { + this.element = element; + this.min = min; + this.max = max; + } + + /** + * Return element + * + * @return + */ + public Element getElement() { + return element; + } + + /** + * Set a value to parameter element. + * + * @param element + */ + public void setElement(Element element) { + this.element = element; + } + + /** + * Return min + * + * @return + */ + public String getMin() { + return min; + } + + /** + * Set a value to parameter min. + * + * @param min + */ + public void setMin(String min) { + this.min = min; + } + + /** + * Return max + * + * @return + */ + public String getMax() { + return max; + } + + /** + * Set a value to parameter max. + * + * @param max + */ + public void setMax(String max) { + this.max = max; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Between)) { + return false; + } + + final Between between = (Between) other; + + if ((element == null && between.getElement() != null) + || (element != null && !element.equals(between.getElement()))) + return false; + if ((min == null && between.getMin() != null) + || (min != null && !min.equals(between.getMin()))) + return false; + if ((max == null && between.getMax() != null) + || (max != null && !max.equals(between.getMax()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/BinaryOperator.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/BinaryOperator.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/BinaryOperator.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,108 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for BinaryOperator --> + * + * <p> + * This class is an abstract class that's used to factor each operator that + * handle two parameters (=, !=, <, <=, >, >=, end, begin). + * </p> + * + * <!-- End of user code for BinaryOperator --> + */ +public class BinaryOperator extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected Element element; + protected String value; + + /** + * Default constructor + */ + public BinaryOperator() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param element + * @param value + */ + public BinaryOperator(Element element, String value) { + this.element = element; + this.value = value; + } + + /** + * Return element + * + * @return + */ + public Element getElement() { + return element; + } + + /** + * Set a value to parameter element. + * + * @param element + */ + public void setElement(Element element) { + this.element = element; + } + + /** + * Return value + * + * @return + */ + public String getValue() { + return value; + } + + /** + * Set a value to parameter value. + * + * @param value + */ + public void setValue(String value) { + this.value = value; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof BinaryOperator)) { + return false; + } + + final BinaryOperator binaryOperator = (BinaryOperator) other; + + if ((element == null && binaryOperator.getElement() != null) + || (element != null && !element.equals(binaryOperator + .getElement()))) + return false; + if ((value == null && binaryOperator.getValue() != null) + || (value != null && !value.equals(binaryOperator.getValue()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Contains.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Contains.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Contains.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,118 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; +import java.util.List; + +// End of user code for import + +/** + * <!-- Start of user code for Contains --> + * + * <p> + * Contains operator is used to build restriction containing "(element like + * *value1 or element like value1*) and (element like *value2 or element like + * value2*)" where element could be a String, a multimedia, a text or an xhtml + * <br> + * <br> + * For example, use: + * <ul> + * <li>RestrictionHelper.contains( myElement , "value1" )</li> + * <li>RestrictionHelper.contains( myElement , "value1", "value2", ... )</li> + * <li>RestrictionHelper.contains( myElement , + * a_list_containing_at_least_one_string )</li> + * </ul> + * </p> + * + * <!-- End of user code for Contains --> + */ +public class Contains extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected Element element; + protected List<String> value; + + /** + * Default constructor + */ + public Contains() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param element + * @param value + */ + public Contains(Element element, List<String> value) { + this.element = element; + this.value = value; + } + + /** + * Return element + * + * @return + */ + public Element getElement() { + return element; + } + + /** + * Set a value to parameter element. + * + * @param element + */ + public void setElement(Element element) { + this.element = element; + } + + /** + * Return value + * + * @return + */ + public List<String> getValue() { + return value; + } + + /** + * Set a value to parameter value. + * + * @param value + */ + public void setValue(List<String> value) { + this.value = value; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Contains)) { + return false; + } + + final Contains contains = (Contains) other; + + if ((element == null && contains.getElement() != null) + || (element != null && !element.equals(contains.getElement()))) + return false; + if ((value == null && contains.getValue() != null) + || (value != null && !value.equals(contains.getValue()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Element.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Element.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Element.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,54 @@ +/* *##% + * Copyright (c) 2009 ruchaud. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ +package org.sharengo.wikitty.search; + +import java.io.Serializable; + +/** + * Search on field + * @author ruchaud + */ +public class Element implements Serializable { + + /** Represent a element on extension */ + public static String ELT_EXTENSION = "elt_extension"; + + /** Represent a element on id */ + public static String ELT_ID = "elt_id"; + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected String name; + + public Element() { + super(); + } + + public Element(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWith.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWith.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWith.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for EndsWith --> + * + * <p> + * EndsWith operator is used to build restriction containing "element like + * *value" where element could be a String, a multimedia, a text or an xhtml + * <br> + * <br> + * For example, use: RestrictionHelper.end( myElement , "value" ) + * </p> + * + * <!-- End of user code for EndsWith --> + */ +public class EndsWith extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public EndsWith() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof EndsWith)) { + return false; + } + + final EndsWith endsWith = (EndsWith) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWithWilcarded.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWithWilcarded.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/EndsWithWilcarded.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for EndsWith --> + * + * <p> + * EndsWith operator is used to build restriction containing "element like + * *value" where element could be a String, a multimedia, a text or an xhtml + * <br> + * <br> + * For example, use: RestrictionHelper.end( myElement , "value" ) + * </p> + * + * <!-- End of user code for EndsWith --> + */ +public class EndsWithWilcarded extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public EndsWithWilcarded() { + super(); + } + + /** + * Equality test based attributes values + * + * @param other + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof EndsWithWilcarded)) { + return false; + } + + final EndsWithWilcarded endsWith = (EndsWithWilcarded) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Equals.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Equals.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Equals.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for Equals --> + * + * <p> + * Equals operator is used to build restriction containing "element == value" + * where element could be an Id, a String, a multimedia, a closed list, an + * Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.eq( myElement , "REF1234567890" ) + * </p> + * + * <!-- End of user code for Equals --> + */ +public class Equals extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public Equals() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Equals)) { + return false; + } + + final Equals equals = (Equals) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Greater.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Greater.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Greater.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for Greater --> + * + * <p> + * Greater operator is used to build restriction containing "element > value" + * where element could be a Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.less( myElement , + * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * </p> + * + * <!-- End of user code for Greater --> + */ +public class Greater extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public Greater() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Greater)) { + return false; + } + + final Greater greater = (Greater) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/GreaterOrEqual.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/GreaterOrEqual.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/GreaterOrEqual.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for GreaterOrEqual --> + * + * <p> + * GreatOrEqual operator is used to build restriction containing "element >= + * value" where element could be a Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.greatEq( myElement , + * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * </p> + * + * <!-- End of user code for GreaterOrEqual --> + */ +public class GreaterOrEqual extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public GreaterOrEqual() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof GreaterOrEqual)) { + return false; + } + + final GreaterOrEqual greaterOrEqual = (GreaterOrEqual) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/In.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/In.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/In.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,120 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; +import java.util.List; + +// End of user code for import + +/** + * <!-- Start of user code for Contains --> + * + * <p> + * Contains operator is used to build restriction containing "(element like + * *value1 or element like value1*) and (element like *value2 or element like + * value2*)" where element could be a String, a multimedia, a text or an xhtml + * <br> + * <br> + * For example, use: + * <ul> + * <li>RestrictionHelper.contains( myElement , "value1" )</li> + * <li>RestrictionHelper.contains( myElement , "value1", "value2", ... )</li> + * <li>RestrictionHelper.contains( myElement , + * a_list_containing_at_least_one_string )</li> + * </ul> + * </p> + * + * <!-- End of user code for Contains --> + */ +public class In extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected Element element; + protected List<String> value; + + /** + * Default constructor + */ + public In() { + super(); + name = RestrictionName.IN; + } + + /** + * Constructor with all parameters initialized + * + * @param element + * @param value + */ + public In(Element element, List<String> value) { + this.element = element; + this.value = value; + name = RestrictionName.IN; + } + + /** + * Return element + * + * @return + */ + public Element getElement() { + return element; + } + + /** + * Set a value to parameter element. + * + * @param element + */ + public void setElement(Element element) { + this.element = element; + } + + /** + * Return value + * + * @return + */ + public List<String> getValue() { + return value; + } + + /** + * Set a value to parameter value. + * + * @param value + */ + public void setValue(List<String> value) { + this.value = value; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof In)) { + return false; + } + + final In contains = (In) other; + + if ((element == null && contains.getElement() != null) + || (element != null && !element.equals(contains.getElement()))) + return false; + if ((value == null && contains.getValue() != null) + || (value != null && !value.equals(contains.getValue()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Keyword.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Keyword.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Keyword.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,42 @@ +/* *##% + * Copyright (c) 2009 ruchaud. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ +package org.sharengo.wikitty.search; + +/** + * Search keyword in all wikitty + * @author ruchaud + */ +public class Keyword extends Restriction { + + protected String value; + + public Keyword() { + } + + public Keyword(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Less.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Less.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Less.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for Less --> + * + * <p> + * Less operator is used to build restriction containing "element < value" + * where element could be a Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.less( myElement , + * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * </p> + * + * <!-- End of user code for Less --> + */ +public class Less extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public Less() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Less)) { + return false; + } + + final Less less = (Less) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/LessOrEqual.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/LessOrEqual.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/LessOrEqual.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for LessOrEqual --> + * + * <p> + * LessOrEqual operator is used to build restriction containing "element <= + * value" where element could be a Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.lessEq( myElement , + * RestrictionHelper.DATE_FORMAT.format(new Date()) ) + * </p> + * + * <!-- End of user code for LessOrEqual --> + */ +public class LessOrEqual extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public LessOrEqual() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof LessOrEqual)) { + return false; + } + + final LessOrEqual lessOrEqual = (LessOrEqual) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Not.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Not.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Not.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,87 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for Not --> + * + * <p> + * Not operator is used to build negative restriction for request on content. + * <br> + * <br> + * For example, use: RestrictionHelper.not( RestrictionHelper.eq( myElement , + * "myValue" ) ) + * </p> + * + * <!-- End of user code for Not --> + */ +public class Not extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected Restriction restriction; + + /** + * Default constructor + */ + public Not() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param restriction + */ + public Not(Restriction restriction) { + this.restriction = restriction; + } + + /** + * Return restriction + * + * @return + */ + public Restriction getRestriction() { + return restriction; + } + + /** + * Set a value to parameter restriction. + * + * @param restriction + */ + public void setRestriction(Restriction restriction) { + this.restriction = restriction; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Not)) { + return false; + } + + final Not not = (Not) other; + + if ((restriction == null && not.getRestriction() != null) + || (restriction != null && !restriction.equals(not + .getRestriction()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/NotEquals.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/NotEquals.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/NotEquals.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for NotEquals --> + * + * <p> + * NotEquals operator is used to build restriction containing "element != value" + * where element could be an Id, a String, a multimedia, a closed list, an + * Integer, a Float or a Date. <br> + * <br> + * For example, use: RestrictionHelper.neq( myElement , "REF1234567890" ) + * </p> + * + * <!-- End of user code for NotEquals --> + */ +public class NotEquals extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public NotEquals() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof NotEquals)) { + return false; + } + + final NotEquals notEquals = (NotEquals) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Or.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Or.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Or.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,93 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; +import java.util.List; + +// End of user code for import + +/** + * <!-- Start of user code for Or --> + * + * <p> + * Or operator is used to build disjunctive restriction for request on content. + * It take at least 2 args. <br> + * <br> + * For example, use: + * <ul> + * <li>RestrictionHelper.or( restriction1, restriction2 )</li> + * <li>RestrictionHelper.or( restriction1, restriction2, restriction3 )</li> + * <li>RestrictionHelper.or( + * my_JavaUtilList_Of_Restriction_Witch_Size_Is_Upper_Than2 )</li> + * </ul> + * </p> + * + * <!-- End of user code for Or --> + */ +public class Or extends Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected List<Restriction> restrictions; + + /** + * Default constructor + */ + public Or() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param restrictions + */ + public Or(List<Restriction> restrictions) { + this.restrictions = restrictions; + } + + /** + * Return restrictions + * + * @return + */ + public List<Restriction> getRestrictions() { + return restrictions; + } + + /** + * Set a value to parameter restrictions. + * + * @param restrictions + */ + public void setRestrictions(List<Restriction> restrictions) { + this.restrictions = restrictions; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Or)) { + return false; + } + + final Or or = (Or) other; + + if ((restrictions == null && or.getRestrictions() != null) + || (restrictions != null && !restrictions.equals(or + .getRestrictions()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Restriction.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Restriction.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Restriction.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,83 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for RestrictionDto --> + * + * <p> + * This element is a symbolic interface implemented by all operators used to + * request contents (And, Or, Not, Equals, NotEquals, EndsWith, ...). + * </p> + * + * <!-- End of user code for RestrictionDto --> + */ +public class Restriction implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + protected RestrictionName name; + + /** + * Default constructor + */ + public Restriction() { + super(); + } + + /** + * Constructor with all parameters initialized + * + * @param name + */ + public Restriction(RestrictionName name) { + this.name = name; + } + + /** + * Return name + * + * @return + */ + public RestrictionName getName() { + return name; + } + + /** + * Set a value to parameter name. + * + * @param name + */ + public void setName(RestrictionName name) { + this.name = name; + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Restriction)) { + return false; + } + + final Restriction restrictionDto = (Restriction) other; + + if ((name == null && restrictionDto.getName() != null) + || (name != null && !name.equals(restrictionDto.getName()))) + return false; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionHelper.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionHelper.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionHelper.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,206 @@ +package org.sharengo.wikitty.search; + +import java.text.SimpleDateFormat; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + + + +/** + * @author "Nicolas Chapurlat" <nicolas.chapurlat@logica.com> + * + * This class allow you to simply create restriction. <br> + * <br> + * Exmaples : <br> + * <br> + * RestrictionHelper.and(<br> + * RestrictionHelper.eq(<br> + * new + * ElementDto(ElementName.CONTENT_DEFINITION, OperandName.ID, OperandType.ID),<br> + * "myContentDefId"),<br> + * RestrictionHelper.between(<br> + * new ElementDto(ElementName.CONTENT, + * OperandName.CREATION_DATE, OperandType.DATE),<br> + * RestrictionHelper.DATE_FORMAT.format (new + * Date(2008,1,25)),<br> + * RestrictionHelper.DATE_FORMAT.format (new + * Date(2008,6,15))));<br> ); <br> + * <br> -- example 2 : I search all content witch content definition id is + * "myContentDefId" and attribute def 'ref' witch id is ATT_REF_ID is not equals + * to "REF1234567890" <br> + * <br> + * RestrictionHelper.and(<br> + * RestrictionHelper.eq(<br> + * new + * ElementDto(ElementName.CONTENT_DEFINITION, OperandName.ID, OperandType.ID),<br> + * "myContentDefId"),<br> + * RestrictionHelper.neq(<br> + * new ElementDto(ElementName.ATTRIBUTE, + * "ATT_REF_ID", OperandType.STRING),<br> + * "REF1234567890"));<br> ); <br> + */ +public class RestrictionHelper { + + public static Restriction eq(Element element, String value) { + Equals eq = new Equals(); + eq.setName(RestrictionName.EQUALS); + eq.setElement(element); + eq.setValue(value); + return eq; + } + + public static Restriction neq(Element element, String value) { + NotEquals neq = new NotEquals(); + neq.setName(RestrictionName.NOT_EQUALS); + neq.setElement(element); + neq.setValue(value); + return neq; + } + + public static Restriction less(Element element, String value) { + Less less = new Less(); + less.setName(RestrictionName.LESS); + less.setElement(element); + less.setValue(value); + return less; + } + + public static Restriction lessEq(Element element, String value) { + LessOrEqual lessEq = new LessOrEqual(); + lessEq.setName(RestrictionName.LESS_OR_EQUAL); + lessEq.setElement(element); + lessEq.setValue(value); + return lessEq; + } + + public static Restriction great(Element element, String value) { + Greater great = new Greater(); + great.setName(RestrictionName.GREATER); + great.setElement(element); + great.setValue(value); + return great; + } + + public static Restriction greatEq(Element element, String value) { + GreaterOrEqual greatEq = new GreaterOrEqual(); + greatEq.setName(RestrictionName.GREATER_OR_EQUAL); + greatEq.setElement(element); + greatEq.setValue(value); + return greatEq; + } + + public static Restriction start(Element element, String value) { + StartsWith start = new StartsWith(); + start.setName(RestrictionName.STARTS_WITH); + start.setElement(element); + start.setValue(value); + return start; + } + + public static Restriction end(Element element, String value) { + EndsWith end = new EndsWith(); + end.setName(RestrictionName.ENDS_WITH); + end.setElement(element); + end.setValue(value); + return end; + } + + public static Restriction between(Element element, String min, + String max) { + Between between = new Between(element, min, max); + between.setName(RestrictionName.BETWEEN); + return between; + } + + public static Restriction contains(Element element, String value1, + String... otherValues) { + List<String> values = new LinkedList<String>(); + values.add(value1); + for (String val : otherValues) { + values.add(val); + } + return contains(element, values); + } + + public static Contains contains(Element element, + List<String> values) { + Contains contains = new Contains(element, values); + contains.setName(RestrictionName.CONTAINS); + return contains; + } + + public static Restriction not(Restriction restriction) { + Not not = new Not(restriction); + not.setName(RestrictionName.NOT); + return not; + } + + public static Restriction and(Restriction restriction1, + Restriction restriction2, Restriction... otherRestrictions) { + List<Restriction> restrictions = new LinkedList<Restriction>(); + restrictions.add(restriction1); + restrictions.add(restriction2); + for (Restriction rest : otherRestrictions) { + restrictions.add(rest); + } + return and(restrictions); + } + + public static And and(List<Restriction> restrictions) { + And and = new And(restrictions); + and.setName(RestrictionName.AND); + return and; + } + + public static Or or(Restriction restriction1, + Restriction restriction2, Restriction... otherRestrictions) { + List<Restriction> restrictions = new LinkedList<Restriction>(); + restrictions.add(restriction1); + restrictions.add(restriction2); + for (Restriction rest : otherRestrictions) { + restrictions.add(rest); + } + return or(restrictions); + } + + public static Or or(List<Restriction> restrictions) { + Or or = new Or(restrictions); + or.setName(RestrictionName.OR); + return or; + } + + public static Restriction rTrue() { + Restriction rTrue = new Restriction(); + rTrue.setName(RestrictionName.TRUE); + return rTrue; + } + + public static Restriction rFalse() { + Restriction rFalse = new Restriction(); + rFalse.setName(RestrictionName.FALSE); + return rFalse; + } + + public static Keyword keyword(String value) { + Keyword keyword = new Keyword(); + keyword.setName(RestrictionName.KEYWORD); + keyword.setValue(value); + return keyword; + } + + static ThreadLocal<SimpleDateFormat> myFormats = new ThreadLocal<SimpleDateFormat>() { + @Override + protected SimpleDateFormat initialValue() { + SimpleDateFormat ret = new SimpleDateFormat( + "yyyy-MM-dd'T'00:00:00.000'Z/DAY'", Locale.US); + ret.setTimeZone(TimeZone.getTimeZone("UTC")); + return ret; + } + }; + + public static SimpleDateFormat getDateFormat() { + return myFormats.get(); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionName.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionName.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/RestrictionName.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,29 @@ +package org.sharengo.wikitty.search; + + +/** + * <p> + * This enum contains all kind of restriction used to request content. It's used + * by parser to create lucene request from RestrictionDto. + * </p> + */ +public enum RestrictionName { + EQUALS, + NOT_EQUALS, + LESS, + LESS_OR_EQUAL, + GREATER, + GREATER_OR_EQUAL, + CONTAINS, + STARTS_WITH, + ENDS_WITH, + NOT, + AND, + OR, + BETWEEN, + TRUE, + FALSE, + ASSOCIATED, + IN, + KEYWORD +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Search.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Search.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/Search.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,223 @@ +package org.sharengo.wikitty.search; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyUtil; + +/** + * Helper to create a criteria with a restriction + */ +public class Search { + + static private Log log = LogFactory.getLog(Search.class); + + public enum KIND { + AND, OR + } + + KIND kind = KIND.AND; + List<Restriction> restrictions; + List<Search> subSearchs; + + public Search() { + restrictions = new ArrayList<Restriction>(); + subSearchs = new ArrayList<Search>(); + } + + /** + * Create Search query with field in wikitty argument + * + * @param wikitty example use to create query + * @return + */ + static public Search query(Wikitty wikitty) { + Search result = Search.query(); + result.kind = KIND.AND; + // result object must have same extension that wikitty example + for (String extName : wikitty.getExtensionNames()) { + result.eq(Element.ELT_EXTENSION, extName); + } + + for (String fqfieldName : wikitty.fieldNames()) { + Object value = wikitty.getFqField(fqfieldName); + if (value != null) { // FIXME poussin 20090830 how to search for null value in field ? + FieldType type = wikitty.getFieldType(fqfieldName); + if (type.isCollection()) { + Collection collection = (Collection) value; + for (Object o : collection) { + String strValue = WikittyUtil.toString(type, o); + result.eq(fqfieldName, strValue); + } + } else { + String strValue = WikittyUtil.toString(type, value); + result.eq(fqfieldName, strValue); + } + } + } + + return result; + } + + public static Search query() { + Search search = new Search(); + search.kind = KIND.AND; + return search; + } + + public static Search query(KIND kind) { + Search search = new Search(); + search.kind = kind; + return search; + } + + /** + * Create new query on existant criteria to add new constraint to existant + * criteria + * @param criteria + * @return + */ + public static Search query(Criteria criteria) { + Search search = query(); + search.restrictions.add(criteria.getRestriction()); + return search; + } + + private static Element elt(String element) { + Element elm = new Element(); + elm.setName(element); + return elm; + } + + protected Search handle( Restriction dto ) { + restrictions.add( dto ); + return this; + } + + public Search contains(String element, Collection<String> values) { + return handle( RestrictionHelper.contains(elt(element), + new ArrayList<String>(values)) ); + } + + public Search eq(String element, String value) { + return handle( RestrictionHelper.eq(elt(element), value) ); + } + + public Search neq(String element, String value) { + return handle( RestrictionHelper.neq(elt(element), value) ); + } + + public Search gt(String element, String value) { + return handle( RestrictionHelper.great(elt(element), value) ); + } + + public Search ge(String element, String value) { + return handle( RestrictionHelper.greatEq(elt(element), value) ); + } + + public Search lt(String element, String value) { + return handle( RestrictionHelper.less(elt(element), value) ); + } + + public Search le(String element, String value) { + return handle( RestrictionHelper.lessEq(elt(element), value) ); + } + + public Search bw(String element, String lowerValue, String upperValue) { + return handle( RestrictionHelper.between(elt(element), lowerValue, upperValue) ); + } + + public Search sw(String element, String value) { + return handle( RestrictionHelper.start(elt(element), value) ); + } + + public Search nsw(String element, String value) { + return handle( RestrictionHelper.not( + RestrictionHelper.start(elt(element), value)) ); + } + + public Search ew(String element, String value) { + return handle( RestrictionHelper.end(elt(element), value) ); + } + + public Search notew(String element, String value) { + return handle( RestrictionHelper.not( + RestrictionHelper.end(elt(element), value)) ); + } + + public Search keyword(String value) { + return handle(RestrictionHelper.keyword(value)); + } + + public Search or() { + Search search = Search.query(KIND.OR); + subSearchs.add(search); + return search; + } + + public Search and() { + Search search = Search.query(KIND.AND); + subSearchs.add(search); + return search; + } + + public Search associated(String foreignFieldName) { + Search search = new SubSearch( foreignFieldName, this ); + return search; + } + + /** + * return unnamed criteria + * @return new criteria + */ + public Criteria criteria(String name) { + Criteria criteria = new Criteria(name); + Restriction result = getRestrictions(); + criteria.setRestriction(result); + return criteria; + } + + protected Restriction getRestrictions() throws UnsupportedOperationException { + Restriction result; + if (restrictions.isEmpty() && subSearchs.isEmpty()) { + result = RestrictionHelper.rFalse(); + } else if (restrictions.size() == 1 && subSearchs.isEmpty()) { + result = restrictions.remove(0); + } else if (subSearchs.size() == 1 && restrictions.isEmpty()) { + Search subSearch = subSearchs.get(0); + result = subSearch.getRestrictions(); + } else { + List<Restriction> allRestrictions = new ArrayList<Restriction>(restrictions); + for (Search subSearch : subSearchs) { + Restriction restriction = subSearch.getRestrictions(); + allRestrictions.add(restriction); + } + switch (kind) { + case OR: + result = RestrictionHelper.or(allRestrictions); + break; + case AND: + result = RestrictionHelper.and(allRestrictions); + break; + default: + throw new UnsupportedOperationException("Can't handle restriction kind " + kind.name()); + } + } + return result; + } + + /** + * return criteria with name + * @param name name of criteria + * @return new criteria + */ + public Criteria criteria() { + return criteria(null); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SearchOperand.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SearchOperand.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SearchOperand.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,17 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +// End of user code for import + +/** + * <!-- Start of user code for SearchOperand --> + * <p> + * Represents the possible operands for client search. The supported type of + * each AttributeSearchDto depends of its type. + * </p> + * <!-- End of user code for SearchOperand --> + */ +public enum SearchOperand { + EQUALS, NOT_EQUALS, LESS, LESS_OR_EQUALS, GREATER, GREATER_OR_EQUALS, BEGINS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS, BETWEEN +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/StartsWith.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/StartsWith.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/StartsWith.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,53 @@ +package org.sharengo.wikitty.search; + +// Start of user code for import + +import java.io.Serializable; + +// End of user code for import + +/** + * <!-- Start of user code for StartsWith --> + * + * <p> + * StartsWith operator is used to build restriction containing "element like + * value*" where element could be a String, a multimedia, a text or an xhtml + * <br> + * <br> + * For example, use: RestrictionHelper.start( myElement , "value" ) + * </p> + * + * <!-- End of user code for StartsWith --> + */ +public class StartsWith extends BinaryOperator implements Serializable { + + // serialVersionUID is used for serialization. + private static final long serialVersionUID = 1L; + + /** + * Default constructor + */ + public StartsWith() { + super(); + } + + /** + * Equality test based attributes values + * + * @param value + * Value to compare + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof StartsWith)) { + return false; + } + + final StartsWith startsWith = (StartsWith) other; + + return true; + } + +} \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SubSearch.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SubSearch.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/java/org/sharengo/wikitty/search/SubSearch.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,26 @@ +package org.sharengo.wikitty.search; + +import org.sharengo.wikitty.Criteria; + +public class SubSearch extends Search { + + String foreignName; + Search parent; + + public SubSearch(String foreignFieldName, Search search) { + this.foreignName = foreignFieldName; + this.parent = search; + } + + public Criteria criteria() { + Criteria criteria = super.criteria(); + Criteria result = new Criteria(); + result.setRestriction( new AssociatedRestriction( + parent.criteria().getRestriction(), + criteria.getRestriction(), + new Element(foreignName) + ) ); + return result; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.uml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.uml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.uml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:WikittyProfile="http:///schemas/WikittyProfile/_jQsKkIwQEd6QHYJLLUbpqw/0" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/2.1.0/UML" xsi:schemaLocation="http:///schemas/WikittyProfile/_jQsKkIwQEd6QHYJLLUbpqw/0 ../wikitty-profile/WikittyProfile.uml#_jQsxoYwQEd6QHYJLLUbpqw"> + <uml:Model xmi:id="_qb8akM37EdqwVrslYOdUDA"> + <packagedElement xmi:type="uml:Package" xmi:id="_w8IxIM37EdqwVrslYOdUDA" name="org.sharengo.wikitty"> + <packagedElement xmi:type="uml:Class" xmi:id="_7vSlAIygEd6AV7_7yPcuUg" name="TreeNode"> + <ownedAttribute xmi:id="_I_f20IyhEd6AV7_7yPcuUg" name="name"> + <type xmi:type="uml:PrimitiveType" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"/> + </ownedAttribute> + <ownedAttribute xmi:id="_8U2IoI3eEd6yZLa1tmFRbQ" name="parent" type="_7vSlAIygEd6AV7_7yPcuUg"> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_C-mq4I3fEd6yZLa1tmFRbQ" value="1"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_eYBTEI3fEd6yZLa1tmFRbQ"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_11xXcIyhEd6AV7_7yPcuUg" name="Wikitty"/> + <packagedElement xmi:type="uml:Association" xmi:id="_33YC2oyhEd6AV7_7yPcuUg" name="A_<treeNode>_<wikitty>" memberEnd="_33YC24yhEd6AV7_7yPcuUg _33YC3oyhEd6AV7_7yPcuUg" navigableOwnedEnd="_33YC3oyhEd6AV7_7yPcuUg"> + <ownedEnd xmi:id="_33YC24yhEd6AV7_7yPcuUg" name="treeNode" type="_7vSlAIygEd6AV7_7yPcuUg" association="_33YC2oyhEd6AV7_7yPcuUg"> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_33YC3IyhEd6AV7_7yPcuUg" value="1"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_33YC3YyhEd6AV7_7yPcuUg" value="1"/> + </ownedEnd> + <ownedEnd xmi:id="_33YC3oyhEd6AV7_7yPcuUg" name="children" type="_11xXcIyhEd6AV7_7yPcuUg" isUnique="false" association="_33YC2oyhEd6AV7_7yPcuUg"> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_33YC34yhEd6AV7_7yPcuUg" value="*"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_33YC4IyhEd6AV7_7yPcuUg"/> + </ownedEnd> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_UBOAYIy4Ed6AV7_7yPcuUg" name="Label"> + <ownedAttribute xmi:id="_WJGS4Iy4Ed6AV7_7yPcuUg" name="labels"> + <type xmi:type="uml:PrimitiveType" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_bpNFcIy4Ed6AV7_7yPcuUg" value="*"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_bdtAEIy4Ed6AV7_7yPcuUg"/> + </ownedAttribute> + </packagedElement> + </packagedElement> + <profileApplication xmi:id="_EKzjUIyiEd6AV7_7yPcuUg"> + <eAnnotations xmi:id="_EK1_kIyiEd6AV7_7yPcuUg" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="../wikitty-profile/WikittyProfile.uml#_jQsxoYwQEd6QHYJLLUbpqw"/> + </eAnnotations> + <appliedProfile href="../wikitty-profile/WikittyProfile.uml#_YY_oQIwQEd6QHYJLLUbpqw"/> + </profileApplication> + </uml:Model> + <WikittyProfile:BusinessEntity xmi:id="_Flc8YIyiEd6AV7_7yPcuUg" base_Class="_7vSlAIygEd6AV7_7yPcuUg"/> + <WikittyProfile:BusinessEntity xmi:id="_U54GsIy4Ed6AV7_7yPcuUg" base_Class="_UBOAYIy4Ed6AV7_7yPcuUg"/> +</xmi:XMI> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.umldi =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.umldi (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-api/wikitty-api.umldi 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<diagrams:Diagrams xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.topcased.org/DI/1.0" xmlns:diagrams="http://www.topcased.org/Diagrams/1.0" xmi:id="_1DGZ0IygEd6AV7_7yPcuUg" activeDiagram="_1DGZ0YygEd6AV7_7yPcuUg"> + <model href="wikitty-api.uml#_w8IxIM37EdqwVrslYOdUDA"/> + <diagrams xmi:id="_1DGZ0YygEd6AV7_7yPcuUg" position="0,0" size="100,100" name="wikitty-api" viewport="0,0"> + <property xmi:id="_1DW4gIygEd6AV7_7yPcuUg" key="pageFormatName" value="A4"/> + <property xmi:id="_1DW4gYygEd6AV7_7yPcuUg" key="diagramWidth" value="840"/> + <property xmi:id="_1DW4goygEd6AV7_7yPcuUg" key="diagramHeight" value="1188"/> + <property xmi:id="_1DW4g4ygEd6AV7_7yPcuUg" key="pageMarginName" value="Small Margin"/> + <property xmi:id="_1DW4hIygEd6AV7_7yPcuUg" key="diagramTopMargin" value="20"/> + <property xmi:id="_1DW4hYygEd6AV7_7yPcuUg" key="diagramBottomMargin" value="20"/> + <property xmi:id="_1DW4hoygEd6AV7_7yPcuUg" key="diagramLeftMargin" value="20"/> + <property xmi:id="_1DXfkIygEd6AV7_7yPcuUg" key="diagramRightMargin" value="20"/> + <property xmi:id="_1DXfkYygEd6AV7_7yPcuUg" key="orientation" value="portrait"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_1DGZ0oygEd6AV7_7yPcuUg" presentation="org.topcased.modeler.uml.classdiagram"> + <element href="wikitty-api.uml#_w8IxIM37EdqwVrslYOdUDA"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_7vO6oIygEd6AV7_7yPcuUg" position="107,60" size="165,-1"> + <anchorage xmi:id="_Q1pTsIyhEd6AV7_7yPcuUg" graphEdge="_Q1rI4IyhEd6AV7_7yPcuUg _33YC0IyhEd6AV7_7yPcuUg"/> + <anchorage xmi:id="_Q1pTsYyhEd6AV7_7yPcuUg" graphEdge="_Q1rI4IyhEd6AV7_7yPcuUg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_7vO6oYygEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_7vSlAIygEd6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_7vO6ooygEd6AV7_7yPcuUg"> + <property xmi:id="_7vO6o4ygEd6AV7_7yPcuUg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_7vO6pIygEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_7vSlAIygEd6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_I_P_MIyhEd6AV7_7yPcuUg" position="0,0" size="-1,-1"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_I_P_MYyhEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_I_f20IyhEd6AV7_7yPcuUg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_7vO6pYygEd6AV7_7yPcuUg"> + <property xmi:id="_7vO6poygEd6AV7_7yPcuUg" key="eStructuralFeatureID" value="47"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_7vO6p4ygEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_7vSlAIygEd6AV7_7yPcuUg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_Q1rI4IyhEd6AV7_7yPcuUg" anchor="_Q1pTsIyhEd6AV7_7yPcuUg _Q1pTsYyhEd6AV7_7yPcuUg"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_Q1rI4YyhEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_Q1rI6oyhEd6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Q1rI4oyhEd6AV7_7yPcuUg" id="srcNameEdgeObject" uDistance="10" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Q1rI44yhEd6AV7_7yPcuUg" id="srcPropertiesEdgeObject" uDistance="25" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Q1rI5IyhEd6AV7_7yPcuUg" id="srcCountEdgeObject" uDistance="3" vDistance="-13"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Q1rI5YyhEd6AV7_7yPcuUg" visible="false" id="targetNameEdgeObject" uDistance="5" vDistance="6"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Q1rI5oyhEd6AV7_7yPcuUg" id="targetPropertiesEdgeObject" uDistance="25" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Q1rI54yhEd6AV7_7yPcuUg" id="targetCountEdgeObject" uDistance="6" vDistance="-4"/> + <contained xsi:type="di:EdgeObjectOffset" xmi:id="_Q1rI6IyhEd6AV7_7yPcuUg" visible="false" id="middleNameEdgeObject" offset="-185,-148"/> + <contained xsi:type="di:EdgeObjectOffset" xmi:id="_Q1rI6YyhEd6AV7_7yPcuUg" id="stereotypeEdgeObject" offset="0,-10"/> + <waypoints>[0, -58, 0, -58]</waypoints> + <waypoints>[-124, -58, -124, -58]</waypoints> + <waypoints>[-124, 0, -124, 0]</waypoints> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_11wJUIyhEd6AV7_7yPcuUg" position="381,75" size="65,-1"> + <anchorage xmi:id="_33WNoIyhEd6AV7_7yPcuUg" graphEdge="_33YC0IyhEd6AV7_7yPcuUg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_11wJUYyhEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_11xXcIyhEd6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_11wJUoyhEd6AV7_7yPcuUg"> + <property xmi:id="_11wJU4yhEd6AV7_7yPcuUg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_11wJVIyhEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_11xXcIyhEd6AV7_7yPcuUg"/> + </semanticModel> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_11wJVYyhEd6AV7_7yPcuUg"> + <property xmi:id="_11wJVoyhEd6AV7_7yPcuUg" key="eStructuralFeatureID" value="47"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_11wJV4yhEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_11xXcIyhEd6AV7_7yPcuUg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_33YC0IyhEd6AV7_7yPcuUg" anchor="_Q1pTsIyhEd6AV7_7yPcuUg _33WNoIyhEd6AV7_7yPcuUg"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_33YC0YyhEd6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_33YC2oyhEd6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_33YC0oyhEd6AV7_7yPcuUg" visible="false" id="srcNameEdgeObject" uDistance="10" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_33YC04yhEd6AV7_7yPcuUg" id="srcPropertiesEdgeObject" uDistance="25" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_33YC1IyhEd6AV7_7yPcuUg" visible="false" id="srcCountEdgeObject" uDistance="10" vDistance="-10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_33YC1YyhEd6AV7_7yPcuUg" id="targetNameEdgeObject" uDistance="10" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_33YC1oyhEd6AV7_7yPcuUg" id="targetPropertiesEdgeObject" uDistance="25" vDistance="10"/> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_33YC14yhEd6AV7_7yPcuUg" id="targetCountEdgeObject" uDistance="10" vDistance="-10"/> + <contained xsi:type="di:EdgeObjectOffset" xmi:id="_33YC2IyhEd6AV7_7yPcuUg" visible="false" id="middleNameEdgeObject" offset="0,10"/> + <contained xsi:type="di:EdgeObjectOffset" xmi:id="_33YC2YyhEd6AV7_7yPcuUg" id="stereotypeEdgeObject" offset="0,-10"/> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_UBMLMIy4Ed6AV7_7yPcuUg" position="107,205" size="165,-1"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_UBMLMYy4Ed6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_UBOAYIy4Ed6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_UBMLMoy4Ed6AV7_7yPcuUg"> + <property xmi:id="_UBMLM4y4Ed6AV7_7yPcuUg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_UBMLNIy4Ed6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_UBOAYIy4Ed6AV7_7yPcuUg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_WJFEwIy4Ed6AV7_7yPcuUg" position="0,0" size="-1,-1"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_WJFEwYy4Ed6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_WJGS4Iy4Ed6AV7_7yPcuUg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_UBMLNYy4Ed6AV7_7yPcuUg"> + <property xmi:id="_UBMLNoy4Ed6AV7_7yPcuUg" key="eStructuralFeatureID" value="47"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_UBMLN4y4Ed6AV7_7yPcuUg" presentation="default"> + <element href="wikitty-api.uml#_UBOAYIy4Ed6AV7_7yPcuUg"/> + </semanticModel> + </contained> + </contained> + </diagrams> +</diagrams:Diagrams> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.uml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.uml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.uml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<uml:Profile xmi:version="2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/2.1.0/UML" xmi:id="_YY_oQIwQEd6QHYJLLUbpqw" name="WikittyProfile"> + <eAnnotations xmi:id="_jQsxoIwQEd6QHYJLLUbpqw" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <contents xmi:type="ecore:EPackage" xmi:id="_YdoDcMIwEd6_JODy9mSjbg" name="WikittyProfile" nsURI="http:///schemas/WikittyProfile/_Ydh80MIwEd6_JODy9mSjbg/2" nsPrefix="WikittyProfile"> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_YdoDccIwEd6_JODy9mSjbg" name="BusinessEntity"> + <eAnnotations xmi:id="_YdoDcsIwEd6_JODy9mSjbg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_Yrr6wIwQEd6QHYJLLUbpqw"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDc8IwEd6_JODy9mSjbg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_YdoDdcIwEd6_JODy9mSjbg" name="Service"> + <eAnnotations xmi:id="_YdoDdsIwEd6_JODy9mSjbg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_8wioYLHIEd654trW0jShSg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDd8IwEd6_JODy9mSjbg" name="base_Interface" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Interface"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_YdoDecIwEd6_JODy9mSjbg" name="Dto"> + <eAnnotations xmi:id="_YdoDesIwEd6_JODy9mSjbg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="__thW4LHIEd654trW0jShSg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDe8IwEd6_JODy9mSjbg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_YdoDfcIwEd6_JODy9mSjbg" name="Dao"> + <eAnnotations xmi:id="_YdoDfsIwEd6_JODy9mSjbg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_BCXC4LHJEd654trW0jShSg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDf8IwEd6_JODy9mSjbg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_YdoDgcIwEd6_JODy9mSjbg" name="Generic"> + <eAnnotations xmi:id="_YdoDgsIwEd6_JODy9mSjbg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_lAJlUMIvEd6_JODy9mSjbg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDg8IwEd6_JODy9mSjbg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_YdoDhcIwEd6_JODy9mSjbg" name="Qualifier"> + <eAnnotations xmi:id="_YdoDhsIwEd6_JODy9mSjbg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_BscxsMIwEd6_JODy9mSjbg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDh8IwEd6_JODy9mSjbg" name="type" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDicIwEd6_JODy9mSjbg" name="base_Parameter" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Parameter"/> + </eStructuralFeatures> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_YdoDi8IwEd6_JODy9mSjbg" name="base_Property" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Property"/> + </eStructuralFeatures> + </eClassifiers> + </contents> + <contents xmi:type="ecore:EPackage" xmi:id="_Utqv4LHJEd654trW0jShSg" name="WikittyProfile" nsURI="http:///schemas/WikittyProfile/_Uto6sLHJEd654trW0jShSg/1" nsPrefix="WikittyProfile"> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_Utqv4bHJEd654trW0jShSg" name="BusinessEntity"> + <eAnnotations xmi:id="_Utqv4rHJEd654trW0jShSg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_Yrr6wIwQEd6QHYJLLUbpqw"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_Utqv47HJEd654trW0jShSg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_Utqv5bHJEd654trW0jShSg" name="Service"> + <eAnnotations xmi:id="_Utqv5rHJEd654trW0jShSg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_8wioYLHIEd654trW0jShSg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_Utqv57HJEd654trW0jShSg" name="base_Interface" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Interface"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_Utqv6bHJEd654trW0jShSg" name="Dto"> + <eAnnotations xmi:id="_Utqv6rHJEd654trW0jShSg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="__thW4LHIEd654trW0jShSg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_Utqv67HJEd654trW0jShSg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_Utqv7bHJEd654trW0jShSg" name="Dao"> + <eAnnotations xmi:id="_Utqv7rHJEd654trW0jShSg" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_BCXC4LHJEd654trW0jShSg"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_Utqv77HJEd654trW0jShSg" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + </contents> + <contents xmi:type="ecore:EPackage" xmi:id="_jQsxoYwQEd6QHYJLLUbpqw" name="WikittyProfile" nsURI="http:///schemas/WikittyProfile/_jQsKkIwQEd6QHYJLLUbpqw/0" nsPrefix="WikittyProfile"> + <eClassifiers xmi:type="ecore:EClass" xmi:id="_jQsxoowQEd6QHYJLLUbpqw" name="BusinessEntity"> + <eAnnotations xmi:id="_jQsxo4wQEd6QHYJLLUbpqw" source="http://www.eclipse.org/uml2/2.0.0/UML" references="_Yrr6wIwQEd6QHYJLLUbpqw"/> + <eStructuralFeatures xmi:type="ecore:EReference" xmi:id="_jQsxpIwQEd6QHYJLLUbpqw" name="base_Class" ordered="false" lowerBound="1"> + <eType xmi:type="ecore:EClass" href="http://www.eclipse.org/uml2/2.1.0/UML#//Class"/> + </eStructuralFeatures> + </eClassifiers> + </contents> + </eAnnotations> + <elementImport xmi:id="_c0wo8IwQEd6QHYJLLUbpqw"> + <importedElement xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Class"/> + </elementImport> + <elementImport xmi:id="_Nxr1MLHJEd654trW0jShSg"> + <importedElement xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Interface"/> + </elementImport> + <elementImport xmi:id="_ETNYkMIwEd6_JODy9mSjbg"> + <importedElement xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Property"/> + </elementImport> + <elementImport xmi:id="_GW5uoMIwEd6_JODy9mSjbg"> + <importedElement xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Parameter"/> + </elementImport> + <packagedElement xmi:type="uml:Stereotype" xmi:id="_Yrr6wIwQEd6QHYJLLUbpqw" name="BusinessEntity"> + <ownedAttribute xmi:id="_ijbb8owQEd6QHYJLLUbpqw" name="base_Class" association="_ijbb8IwQEd6QHYJLLUbpqw"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Class"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_ijbb8IwQEd6QHYJLLUbpqw" name="Class_BusinessEntity" memberEnd="_ijbb8YwQEd6QHYJLLUbpqw _ijbb8owQEd6QHYJLLUbpqw"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_ijbb8YwQEd6QHYJLLUbpqw" name="extension_BusinessEntity" type="_Yrr6wIwQEd6QHYJLLUbpqw" aggregation="composite" association="_ijbb8IwQEd6QHYJLLUbpqw"/> + </packagedElement> + <packagedElement xmi:type="uml:Stereotype" xmi:id="_8wioYLHIEd654trW0jShSg" name="Service"> + <ownedAttribute xmi:id="_TIsWIrHJEd654trW0jShSg" name="base_Interface" association="_TIsWILHJEd654trW0jShSg"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Interface"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Stereotype" xmi:id="__thW4LHIEd654trW0jShSg" name="Dto"> + <ownedAttribute xmi:id="_JhvC8bHJEd654trW0jShSg" name="base_Class" association="_Jhub47HJEd654trW0jShSg"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Class"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Stereotype" xmi:id="_BCXC4LHJEd654trW0jShSg" name="Dao"> + <ownedAttribute xmi:id="_J1dQMbHJEd654trW0jShSg" name="base_Class" association="_J1cpI7HJEd654trW0jShSg"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Class"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_Jhub47HJEd654trW0jShSg" name="Class_Dto" memberEnd="_JhvC8LHJEd654trW0jShSg _JhvC8bHJEd654trW0jShSg"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_JhvC8LHJEd654trW0jShSg" name="extension_Dto" type="__thW4LHIEd654trW0jShSg" aggregation="composite" association="_Jhub47HJEd654trW0jShSg"/> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_J1cpI7HJEd654trW0jShSg" name="Class_Dao" memberEnd="_J1dQMLHJEd654trW0jShSg _J1dQMbHJEd654trW0jShSg"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_J1dQMLHJEd654trW0jShSg" name="extension_Dao" type="_BCXC4LHJEd654trW0jShSg" aggregation="composite" association="_J1cpI7HJEd654trW0jShSg"/> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_TIsWILHJEd654trW0jShSg" name="Interface_Service" memberEnd="_TIsWIbHJEd654trW0jShSg _TIsWIrHJEd654trW0jShSg"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_TIsWIbHJEd654trW0jShSg" name="extension_Service" type="_8wioYLHIEd654trW0jShSg" aggregation="composite" association="_TIsWILHJEd654trW0jShSg"/> + </packagedElement> + <packagedElement xmi:type="uml:Stereotype" xmi:id="_lAJlUMIvEd6_JODy9mSjbg" name="Generic"> + <ownedAttribute xmi:id="_mmhGMMIvEd6_JODy9mSjbg" name="base_Class" association="_mmfRA8IvEd6_JODy9mSjbg"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Class"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_mmfRA8IvEd6_JODy9mSjbg" name="Class_Generic" memberEnd="_mmfRBMIvEd6_JODy9mSjbg _mmhGMMIvEd6_JODy9mSjbg"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_mmfRBMIvEd6_JODy9mSjbg" name="extension_Generic" type="_lAJlUMIvEd6_JODy9mSjbg" aggregation="composite" association="_mmfRA8IvEd6_JODy9mSjbg"/> + </packagedElement> + <packagedElement xmi:type="uml:Stereotype" xmi:id="_BscxsMIwEd6_JODy9mSjbg" name="Qualifier"> + <ownedAttribute xmi:id="_J2OVMMIwEd6_JODy9mSjbg" name="type"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Class"/> + </ownedAttribute> + <ownedAttribute xmi:id="_SSglAsIwEd6_JODy9mSjbg" name="base_Parameter" association="_SSglAMIwEd6_JODy9mSjbg"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Parameter"/> + </ownedAttribute> + <ownedAttribute xmi:id="_SrqE0sIwEd6_JODy9mSjbg" name="base_Property" association="_SrqE0MIwEd6_JODy9mSjbg"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Property"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_SSglAMIwEd6_JODy9mSjbg" name="Parameter_Qualifier" memberEnd="_SSglAcIwEd6_JODy9mSjbg _SSglAsIwEd6_JODy9mSjbg"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_SSglAcIwEd6_JODy9mSjbg" name="extension_Qualifier" type="_BscxsMIwEd6_JODy9mSjbg" aggregation="composite" association="_SSglAMIwEd6_JODy9mSjbg"/> + </packagedElement> + <packagedElement xmi:type="uml:Extension" xmi:id="_SrqE0MIwEd6_JODy9mSjbg" name="Property_Qualifier" memberEnd="_SrqE0cIwEd6_JODy9mSjbg _SrqE0sIwEd6_JODy9mSjbg"> + <ownedEnd xmi:type="uml:ExtensionEnd" xmi:id="_SrqE0cIwEd6_JODy9mSjbg" name="extension_Qualifier" type="_BscxsMIwEd6_JODy9mSjbg" aggregation="composite" association="_SrqE0MIwEd6_JODy9mSjbg"/> + </packagedElement> +</uml:Profile> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.umldi =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.umldi (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/main/uml/wikitty-profile/WikittyProfile.umldi 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<diagrams:Diagrams xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.topcased.org/DI/1.0" xmlns:diagrams="http://www.topcased.org/Diagrams/1.0" xmi:id="_YY9MAIwQEd6QHYJLLUbpqw" activeDiagram="_YY9zEIwQEd6QHYJLLUbpqw"> + <model href="WikittyProfile.uml#_YY_oQIwQEd6QHYJLLUbpqw"/> + <diagrams xmi:id="_YY9zEIwQEd6QHYJLLUbpqw" position="0,0" size="100,100" name="WikittyProfile" viewport="0,0"> + <property xmi:id="_YZNDoIwQEd6QHYJLLUbpqw" key="pageFormatName" value="A4"/> + <property xmi:id="_YZNDoYwQEd6QHYJLLUbpqw" key="diagramWidth" value="840"/> + <property xmi:id="_YZNDoowQEd6QHYJLLUbpqw" key="diagramHeight" value="1188"/> + <property xmi:id="_YZNDo4wQEd6QHYJLLUbpqw" key="pageMarginName" value="Small Margin"/> + <property xmi:id="_YZNDpIwQEd6QHYJLLUbpqw" key="diagramTopMargin" value="20"/> + <property xmi:id="_YZNDpYwQEd6QHYJLLUbpqw" key="diagramBottomMargin" value="20"/> + <property xmi:id="_YZNDpowQEd6QHYJLLUbpqw" key="diagramLeftMargin" value="20"/> + <property xmi:id="_YZNDp4wQEd6QHYJLLUbpqw" key="diagramRightMargin" value="20"/> + <property xmi:id="_YZNDqIwQEd6QHYJLLUbpqw" key="orientation" value="portrait"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_YY9zEYwQEd6QHYJLLUbpqw" presentation="org.topcased.modeler.uml.profilediagram"> + <element href="WikittyProfile.uml#_YY_oQIwQEd6QHYJLLUbpqw"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_YrqsoIwQEd6QHYJLLUbpqw" position="161,79" size="138,-1"> + <anchorage xmi:id="_ijZmwIwQEd6QHYJLLUbpqw" graphEdge="_ija04IwQEd6QHYJLLUbpqw"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_YrqsoYwQEd6QHYJLLUbpqw" presentation="default"> + <element href="WikittyProfile.uml#_Yrr6wIwQEd6QHYJLLUbpqw"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_YrqsoowQEd6QHYJLLUbpqw"> + <property xmi:id="_Yrqso4wQEd6QHYJLLUbpqw" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_YrqspIwQEd6QHYJLLUbpqw" presentation="default"> + <element href="WikittyProfile.uml#_Yrr6wIwQEd6QHYJLLUbpqw"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_c0kbsIwQEd6QHYJLLUbpqw" position="350,52" size="120,-1"> + <anchorage xmi:id="_ijZmwYwQEd6QHYJLLUbpqw" graphEdge="_ija04IwQEd6QHYJLLUbpqw _Jhub4LHJEd654trW0jShSg _J1cpILHJEd654trW0jShSg _mmfRAMIvEd6_JODy9mSjbg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_c0kbsYwQEd6QHYJLLUbpqw" presentation="default"> + <element href="WikittyProfile.uml#_c0wo8IwQEd6QHYJLLUbpqw"/> + </semanticModel> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_ija04IwQEd6QHYJLLUbpqw" anchor="_ijZmwIwQEd6QHYJLLUbpqw _ijZmwYwQEd6QHYJLLUbpqw"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_ija04YwQEd6QHYJLLUbpqw" presentation="default"> + <element href="WikittyProfile.uml#_ijbb8IwQEd6QHYJLLUbpqw"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_ija04owQEd6QHYJLLUbpqw" id="requiredFieldEdgeObject"/> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_8wgzMLHIEd654trW0jShSg" position="5,161" size="140,-1"> + <anchorage xmi:id="_TIrIALHJEd654trW0jShSg" graphEdge="_TIrvELHJEd654trW0jShSg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_8wgzMbHIEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_8wioYLHIEd654trW0jShSg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_8wgzMrHIEd654trW0jShSg"> + <property xmi:id="_8wgzM7HIEd654trW0jShSg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_8wgzNLHIEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_8wioYLHIEd654trW0jShSg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="__tgIwLHIEd654trW0jShSg" position="322,175" size="140,-1"> + <anchorage xmi:id="_JhtNwLHJEd654trW0jShSg" graphEdge="_Jhub4LHJEd654trW0jShSg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="__tgIwbHIEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#__thW4LHIEd654trW0jShSg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="__tgIwrHIEd654trW0jShSg"> + <property xmi:id="__tgIw7HIEd654trW0jShSg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="__tgIxLHIEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#__thW4LHIEd654trW0jShSg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_BCV0wLHJEd654trW0jShSg" position="480,172" size="140,-1"> + <anchorage xmi:id="_J1bbALHJEd654trW0jShSg" graphEdge="_J1cpILHJEd654trW0jShSg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_BCV0wbHJEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_BCXC4LHJEd654trW0jShSg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_BCV0wrHJEd654trW0jShSg"> + <property xmi:id="_BCV0w7HJEd654trW0jShSg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_BCV0xLHJEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_BCXC4LHJEd654trW0jShSg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_Jhub4LHJEd654trW0jShSg" anchor="_JhtNwLHJEd654trW0jShSg _ijZmwYwQEd6QHYJLLUbpqw"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_Jhub4bHJEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_Jhub47HJEd654trW0jShSg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_Jhub4rHJEd654trW0jShSg" id="requiredFieldEdgeObject"/> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_J1cpILHJEd654trW0jShSg" anchor="_J1bbALHJEd654trW0jShSg _ijZmwYwQEd6QHYJLLUbpqw"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_J1cpIbHJEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_J1cpI7HJEd654trW0jShSg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_J1cpIrHJEd654trW0jShSg" id="requiredFieldEdgeObject"/> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_NxfA4LHJEd654trW0jShSg" position="10,36" size="120,-1"> + <anchorage xmi:id="_TIrIAbHJEd654trW0jShSg" graphEdge="_TIrvELHJEd654trW0jShSg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_NxfA4bHJEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_Nxr1MLHJEd654trW0jShSg"/> + </semanticModel> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_TIrvELHJEd654trW0jShSg" anchor="_TIrIALHJEd654trW0jShSg _TIrIAbHJEd654trW0jShSg"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_TIrvEbHJEd654trW0jShSg" presentation="default"> + <element href="WikittyProfile.uml#_TIsWILHJEd654trW0jShSg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_TIrvErHJEd654trW0jShSg" id="requiredFieldEdgeObject"/> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_k_5tsMIvEd6_JODy9mSjbg" position="164,173" size="140,-1"> + <anchorage xmi:id="_mmcNsMIvEd6_JODy9mSjbg" graphEdge="_mmfRAMIvEd6_JODy9mSjbg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_k_5tscIvEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_lAJlUMIvEd6_JODy9mSjbg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_k_5tssIvEd6_JODy9mSjbg"> + <property xmi:id="_k_5ts8IvEd6_JODy9mSjbg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_k_5ttMIvEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_lAJlUMIvEd6_JODy9mSjbg"/> + </semanticModel> + </contained> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_mmfRAMIvEd6_JODy9mSjbg" anchor="_mmcNsMIvEd6_JODy9mSjbg _ijZmwYwQEd6QHYJLLUbpqw"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_mmfRAcIvEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_mmfRA8IvEd6_JODy9mSjbg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_mmfRAsIvEd6_JODy9mSjbg" id="requiredFieldEdgeObject"/> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_BsbjkMIwEd6_JODy9mSjbg" position="164,402" size="140,-1"> + <anchorage xmi:id="_SSf98MIwEd6_JODy9mSjbg" graphEdge="_SSf98sIwEd6_JODy9mSjbg _SrpdwMIwEd6_JODy9mSjbg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_BsbjkcIwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_BscxsMIwEd6_JODy9mSjbg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_BsbjksIwEd6_JODy9mSjbg"> + <property xmi:id="_Bsbjk8IwEd6_JODy9mSjbg" key="eStructuralFeatureID" value="37"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_BsbjlMIwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_BscxsMIwEd6_JODy9mSjbg"/> + </semanticModel> + <contained xsi:type="di:GraphNode" xmi:id="_J1_rsMIwEd6_JODy9mSjbg" position="0,0" size="-1,-1"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_J1_rscIwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_J2OVMMIwEd6_JODy9mSjbg"/> + </semanticModel> + </contained> + </contained> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_ES52kMIwEd6_JODy9mSjbg" position="246,299" size="120,-1"> + <anchorage xmi:id="_SroPoMIwEd6_JODy9mSjbg" graphEdge="_SrpdwMIwEd6_JODy9mSjbg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_ES52kcIwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_ETNYkMIwEd6_JODy9mSjbg"/> + </semanticModel> + </contained> + <contained xsi:type="di:GraphNode" xmi:id="_GW5HkMIwEd6_JODy9mSjbg" position="79,290" size="120,-1"> + <anchorage xmi:id="_SSf98cIwEd6_JODy9mSjbg" graphEdge="_SSf98sIwEd6_JODy9mSjbg"/> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_GW5HkcIwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_GW5uoMIwEd6_JODy9mSjbg"/> + </semanticModel> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_SSf98sIwEd6_JODy9mSjbg" anchor="_SSf98MIwEd6_JODy9mSjbg _SSf98cIwEd6_JODy9mSjbg"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_SSf988IwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_SSglAMIwEd6_JODy9mSjbg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_SSf99MIwEd6_JODy9mSjbg" id="requiredFieldEdgeObject"/> + </contained> + <contained xsi:type="di:GraphEdge" xmi:id="_SrpdwMIwEd6_JODy9mSjbg" anchor="_SSf98MIwEd6_JODy9mSjbg _SroPoMIwEd6_JODy9mSjbg"> + <semanticModel xsi:type="di:EMFSemanticModelBridge" xmi:id="_SrpdwcIwEd6_JODy9mSjbg" presentation="default"> + <element href="WikittyProfile.uml#_SrqE0MIwEd6_JODy9mSjbg"/> + </semanticModel> + <contained xsi:type="di:EdgeObjectUV" xmi:id="_SrpdwsIwEd6_JODy9mSjbg" id="requiredFieldEdgeObject"/> + </contained> + </diagrams> +</diagrams:Diagrams> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/AllTests.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/AllTests.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/AllTests.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,33 @@ +package org.sharengo.wikitty; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.sharengo.wikitty.test.api.CommonTest; +import org.sharengo.wikitty.test.api.ExtensionFactoryTest; +import org.sharengo.wikitty.test.api.SearchCriteriaTest; +import org.sharengo.wikitty.test.api.WikittyUtilTest; +import org.sharengo.wikitty.test.conform.SearchApiTest; +import org.sharengo.wikitty.test.conform.StorageTest; +import org.sharengo.wikitty.test.memory.InMemoryStorageTest; + +@RunWith(Suite.class) +@SuiteClasses({ + /* + * Commons API Tests + */ + CommonTest.class, + ExtensionFactoryTest.class, + SearchCriteriaTest.class, + WikittyUtilTest.class, + /* + * Conformance Tests + */ + SearchApiTest.class, + StorageTest.class, + /* + * InMemory specifics Tests + */ + InMemoryStorageTest.class +}) +public class AllTests {} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/AbstractTestApi.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/AbstractTestApi.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/AbstractTestApi.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,13 @@ +package org.sharengo.wikitty.test.api; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.internal.runners.JUnit4ClassRunner; +import org.junit.runner.RunWith; + +@RunWith(JUnit4ClassRunner.class) +public abstract class AbstractTestApi { + + protected final static Log log = LogFactory.getLog(AbstractTestApi.class); + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/CommonTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/CommonTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/CommonTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,385 @@ +package org.sharengo.wikitty.test.api; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; +import org.sharengo.wikitty.ExtensionFactory; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyException; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.FieldType.TYPE; + +/** + * Test Wikitty, Extensions, Field and FieldType through the Wikitty Object + * + * @author guillaumed + * + */ +public class CommonTest extends AbstractTestApi { + + static private Log log = LogFactory.getLog(CommonTest.class); + private static String + UNKNOWN = "unknown", + EXTNAME = "ExtName"; + + @Test + public void testWikittyId() throws Exception { + Wikitty w = new Wikitty(); + // as soon as a wikitty object is created, it got an ID. + assertNotNull("Wikitty should got an ID", w.getId() ); + + Wikitty w2 = new Wikitty( w.getId() ); + // two wikitty with a similar id are equals. + assertEquals("Wikitty with same ID must be equals", w, w2); + } + + @Test + public void testWikittyExtension() throws Exception { + + Wikitty wikitty = new Wikitty(); + + // null extension should be ignored + WikittyExtension ext = new WikittyExtension( "invalidExt", "1", null, null ); + wikitty.addExtension(ext); + // yes we want to handle empty extension + assertTrue( wikitty.hasExtension("invalidExt") ); + + // empty extension should be ignored (?) + ext = new WikittyExtension( "invalideExt2", "1", null, new LinkedHashMap<String, FieldType>() ); + wikitty.addExtension(ext); + assertFalse( wikitty.hasExtension("invalidExt2") ); + + // test requires extension + ext = new WikittyExtension( "master", "1", null, null); + wikitty.addExtension(ext); + assertTrue( wikitty.hasExtension("master") ); + + ext = new WikittyExtension( "slave", "1", "master", null); + wikitty.addExtension(ext); + assertTrue( wikitty.hasExtension("slave") ); + + ext = new WikittyExtension("badslave", "1", "nomaster", null); + try { + wikitty.addExtension(ext); + assertFalse(true); + } catch (Exception eee) { + // add extension that depend another not in wikitty must throw exception + assertTrue(true); + } + assertFalse( wikitty.hasExtension("badslave") ); + + // test data ... + String testExtName = "testExt"; + ext = ExtensionFactory.create(testExtName, "1") + .addField("fieldName0", TYPE.NUMERIC) + .addField("fieldName1", TYPE.STRING) + .addField("fieldName2", TYPE.NUMERIC) + .extension(); + Wikitty w = new Wikitty(); + assertFalse( w.hasExtension(testExtName) ); + w.addExtension(ext); + assertTrue( w.hasExtension(testExtName) ); + for ( int i = 0; i < 3; i++ ) { + String fieldName = "fieldName" + i; + assertTrue( "Field " + fieldName + " not found" + , w.hasField(testExtName, fieldName) ); + } + + // test add an other extension ... + WikittyExtension ext2 = ExtensionFactory.create("otherExt", "1") + .addField("fieldName0", TYPE.NUMERIC) + .addField("fieldName1", TYPE.STRING) + .addField("fieldName2", TYPE.NUMERIC) + .addField("fieldName3", TYPE.NUMERIC) + .addField("fieldName4", TYPE.NUMERIC) + .extension(); + + w.addExtension(ext2); + for ( int i = 0; i < 5; i++ ) { + String fieldName = "fieldName" + i; + if ( i < 3 ) { // fields in the first implem should be kept + assertTrue( "Field " + fieldName + " not found" + , w.hasField(testExtName, fieldName) ); + } + assertTrue( "Field " + fieldName + " not found", + w.hasField("otherExt", fieldName) ); + } + + } + + @Test + public void testFieldAssigment() throws Exception { + Wikitty w = createBasicWikitty(); + + // test assignment on a non-existing extension. + try { + w.setField(UNKNOWN, "fieldName", "fieldValue"); + fail( "Should throw a runtime exception !" ); + } catch (RuntimeException e) { + // OK ! + } + + // test assignment on a non-existing field. + try { + w.setField(EXTNAME, "non-existing-fieldName", "fieldValue"); + fail( "Should throw a runtime exception !" ); + } catch (RuntimeException e) { + // OK ! + } + + // basic valid assignment ... + String stringValue = "A Test Value"; + w.setField(EXTNAME, "fieldName0", stringValue); + assertEquals(stringValue, w.getFieldAsString(EXTNAME, "fieldName0") ); + + int intValue = 123456; + w.setField(EXTNAME, "fieldName1", intValue); + assertEquals(intValue, w.getFieldAsInt(EXTNAME, "fieldName1") ); + + Date dateValue = new Date(); + w.setField(EXTNAME, "fieldName2", new Date() ); + assertEquals(dateValue, w.getFieldAsDate(EXTNAME, "fieldName2") ); + + // null or empty assignment ... + for ( int i = 0; i < 3; i++ ) { + w.setField(EXTNAME, "fieldName" + i, null); + } + + } + + private Wikitty createBasicWikitty() { + WikittyExtension ext = ExtensionFactory.create(EXTNAME, "1") + .addField("name", TYPE.STRING) + .extension(); + Wikitty w = new Wikitty(); + w.setField(EXTNAME, "name", "foobar"); + return w; + } + + @Test + public void testFieldCastRules() throws Exception { + Wikitty w = createBasicWikitty(); + + // casted assignment ... + final String stringValue = "Hello"; + // test any object => string type (casted as its toString() value) + w.setField(EXTNAME, "fieldName0", new Object() { + public String toString() { + return stringValue; + } + }); + // test java.lang.Integer => int + w.setField(EXTNAME, "fieldName1", new Integer(123)); + assertEquals(123, w.getFieldAsInt(EXTNAME, "fieldName1") ); + // test String => int + w.setField(EXTNAME, "fieldName1", "123"); + assertEquals(123, w.getFieldAsInt(EXTNAME, "fieldName1") ); + // test String => Date + Calendar cal = Calendar.getInstance(Locale.ROOT); + cal.set(1982, 0, 23, 0, 0, 0); cal.set( Calendar.MILLISECOND, 0 ); + w.setField( EXTNAME, "fieldName2", WikittyUtil.solrDateFormat.format(cal.getTime()) ); + assertEquals(cal.getTime(), w.getFieldAsDate(EXTNAME, "fieldName2") ); + } + + @Test + public void testFieldBoundsManagement() throws Exception { + String extName = "myExt"; + String fieldName = "fieldName0"; + WikittyExtension ext = ExtensionFactory.create(extName, "1") + .addField(fieldName, TYPE.NUMERIC) + .maxOccur(FieldType.NOLIMIT) + .extension(); + Wikitty w = new Wikitty(); + w.addExtension(ext); + + + // test setting a (primitive) value to the field ... + try { + w.setField(extName, fieldName, 123); + fail("setting an int to a list of int is forbidden !"); + } catch (WikittyException e) { + // OK + } + + // test adding elements to the field ... + for ( int i = 0; i < 10; i++ ) { + w.addToField(extName, fieldName, i); + } + int z = 0; + for ( int value : w.getFieldAsList(extName, fieldName, Integer.class) ) { + assertEquals( "element " + z + " failed", + z, value ); + z++; + } + + // test set a list as the field value ... + Integer[] listInt = new Integer[] {4, 2, 8, 9, 5, -12, Integer.MIN_VALUE, Integer.MAX_VALUE }; + w.setField( extName, fieldName, Arrays.asList(listInt) ); + z = 0; + for ( int value : w.getFieldAsList(extName, fieldName, Integer.class) ) { + assertEquals( listInt[z++].intValue(), value ); + } + + // test remove an element ... + w.removeFromField( extName, fieldName, Integer.MIN_VALUE ); + List<Integer> values = w.getFieldAsList(extName, fieldName, Integer.class); + z = 0; + for ( int value : w.getFieldAsList(extName, fieldName, Integer.class) ) { + assertEquals( + // on the last element, we expect MAX_VALUE because MIN_VALUE was deleted. + z == values.size() - 1 ? Integer.MAX_VALUE : listInt[z++].intValue() + , value ); + } + + // test clear field ... + w.clearField(extName, fieldName); + values = w.getFieldAsList(extName, fieldName, Integer.class); + assertTrue( values.isEmpty() ); + + } + + public static class PerfFieldAccesClass { + String stringValue; + int intValue; + Date dateValue; + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + } + + public int getIntValue() { + return intValue; + } + + public void setDateValue(Date dateValue) { + this.dateValue = dateValue; + } + + public Date getDateValue() { + return dateValue; + } + + } + + @Test + public void testPerfFieldAccess() throws Exception { + int MAX = 100000; + + Map<String, Object> m = new HashMap<String, Object>(); + Wikitty w = createBasicWikitty(); + PerfFieldAccesClass z = new PerfFieldAccesClass(); + + long time = System.currentTimeMillis(); + for (int i=0; i<MAX; i++) { + // basic valid assignment ... + String stringValue = "A Test Value"; + m.put(EXTNAME+".fieldName0", stringValue); + + int intValue = 123456; + m.put(EXTNAME + ".fieldName1", intValue); + + Date dateValue = new Date(); + m.put(EXTNAME + ".fieldName2", new Date()); + } + long timeSetM = System.currentTimeMillis() - time; + + time = System.currentTimeMillis(); + String tmp = ""; + for (int i = 0; i < MAX; i++) { + String stringValue = (String)m.get(EXTNAME + ".fieldName0"); + + int intValue = (Integer) m.get(EXTNAME + ".fieldName1"); + + Date dateValue = (Date)m.get(EXTNAME + ".fieldName2"); + tmp = stringValue + intValue + dateValue; + } + long timeGetM = System.currentTimeMillis() - time; + + + time = System.currentTimeMillis(); + for (int i=0; i<MAX; i++) { + // basic valid assignment ... + String stringValue = "A Test Value"; + w.setField(EXTNAME, "fieldName0", stringValue); + + int intValue = 123456; + w.setField(EXTNAME, "fieldName1", intValue); + + Date dateValue = new Date(); + w.setField(EXTNAME, "fieldName2", new Date()); + } + long timeSetW = System.currentTimeMillis() - time; + + time = System.currentTimeMillis(); + for (int i=0; i<MAX; i++) { + // basic valid assignment ... + String stringValue = w.getFieldAsString(EXTNAME, "fieldName0"); + + int intValue = w.getFieldAsInt(EXTNAME, "fieldName1"); + + Date dateValue = w.getFieldAsDate(EXTNAME, "fieldName2"); + tmp = stringValue + intValue + dateValue; + } + long timeGetW = System.currentTimeMillis() - time; + + time = System.currentTimeMillis(); + for (int i = 0; i < MAX; i++) { + String stringValue = "A Test Value"; + z.setStringValue(stringValue); + + int intValue = 123456; + z.setIntValue(intValue); + + Date dateValue = new Date(); + z.setDateValue(dateValue); + } + long timeSetZ = System.currentTimeMillis() - time; + + time = System.currentTimeMillis(); + for (int i = 0; i < MAX; i++) { + // basic valid assignment ... + String stringValue = z.getStringValue(); + + int intValue = z.getIntValue(); + + Date dateValue = z.getDateValue(); + tmp = stringValue + intValue + dateValue; + } + long timeGetZ = System.currentTimeMillis() - time; + + log.info("Time m set: " + timeSetM + " Time m get: " + timeGetM); + log.info("Time w set: " + timeSetW + " Time w get: " + timeGetW); + log.info("Time z set: " + timeSetZ + " Time z get: " + timeGetZ); + } + + /** main is used for profile test */ + public static void main(String [] args) throws Exception { + new CommonTest().testPerfFieldAccess(); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/ExtensionFactoryTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/ExtensionFactoryTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/ExtensionFactoryTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,46 @@ +package org.sharengo.wikitty.test.api; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +import org.junit.Test; +import org.sharengo.wikitty.ExtensionFactory; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.FieldType.TYPE; + +public class ExtensionFactoryTest extends AbstractTestApi { + + @Test + public void testExtensionFactory() throws Exception { + WikittyExtension ext = ExtensionFactory.create("testExtension", "1.0") + .addField("name", TYPE.STRING) + .addField("phoneNumbers", TYPE.STRING) + .minOccur(2) + .maxOccur(10) + .addField("matricule", TYPE.NUMERIC) + .unique() + .addField("fired", TYPE.BOOLEAN) + .extension(); + + assertEquals("testExtension", ext.getName()); + assertEquals("1.0", ext.getVersion()); + checkField( ext, "name", TYPE.STRING, 0, 1, false); + checkField( ext, "phoneNumbers", TYPE.STRING, 2, 10, false); + checkField( ext, "matricule", TYPE.NUMERIC, 0, 1, true); + checkField( ext, "fired", TYPE.BOOLEAN, 0, 1, false); + + } + + private void checkField( WikittyExtension ext, String fieldName, TYPE type, int min, int max, boolean unique) { + FieldType fieldType = ext.getFieldType(fieldName); + String str = "Checking " + ext.getName() + "." + fieldName + " field..."; + assertNotNull(str, fieldType ); + assertEquals(str, type, fieldType.getType()); + assertEquals(str, min, fieldType.getLowerBound()); + assertEquals(str, max, fieldType.getUpperBound()); + assertEquals(str, unique, fieldType.isUnique()); + } + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/SearchCriteriaTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/SearchCriteriaTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/SearchCriteriaTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,154 @@ +package org.sharengo.wikitty.test.api; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.search.And; +import org.sharengo.wikitty.search.AssociatedRestriction; +import org.sharengo.wikitty.search.Between; +import org.sharengo.wikitty.search.BinaryOperator; +import org.sharengo.wikitty.search.Equals; +import org.sharengo.wikitty.search.Or; +import org.sharengo.wikitty.search.Restriction; +import org.sharengo.wikitty.search.RestrictionName; +import org.sharengo.wikitty.search.Search; + +public class SearchCriteriaTest extends AbstractTestApi { + + static private Log log = LogFactory.getLog(SearchCriteriaTest.class); + + String elementName = "ELM_NAME", + value = "Value"; + + @Test + public void testBinaryOperators() throws Exception { + checkSearch( q().eq(elementName, value), RestrictionName.EQUALS ); + checkSearch( q().neq(elementName, value), RestrictionName.NOT_EQUALS ); + checkSearch( q().lt(elementName, value), RestrictionName.LESS ); + checkSearch( q().le(elementName, value), RestrictionName.LESS_OR_EQUAL ); + checkSearch( q().gt(elementName, value), RestrictionName.GREATER ); + checkSearch( q().ge(elementName, value), RestrictionName.GREATER_OR_EQUAL ); + checkSearch( q().sw(elementName, value), RestrictionName.STARTS_WITH ); + checkSearch( q().ew(elementName, value), RestrictionName.ENDS_WITH ); + } + + @Test + public void testBetween() throws Exception { + Criteria criteria = q().bw(elementName, "from", "to").criteria(); + Restriction restriction = criteria.getRestriction(); + assertTrue( restriction instanceof Between ); + Between between = (Between) restriction; + assertEquals( "from", between.getMin() ); + assertEquals( "to", between.getMax() ); + } + + @Test + public void testAnd() throws Exception { + Restriction dto = q() + .eq(elementName + "0", value + "0") + .gt(elementName + "1", value + "1") + .ew(elementName + "2", value + "2") + .criteria().getRestriction(); + assertTrue( dto instanceof And ); + And and = (And) dto; + Restriction[] dtos = and.getRestrictions().toArray(new Restriction[]{}); + checkRestriction(dtos[0], RestrictionName.EQUALS, elementName + "0", value + "0"); + checkRestriction(dtos[1], RestrictionName.GREATER, elementName + "1", value + "1"); + checkRestriction(dtos[2], RestrictionName.ENDS_WITH, elementName + "2", value + "2"); + } + + @Test + public void testOr() throws Exception { + String[] elementNames = new String[4]; + String[] values = new String[4]; + + for (int i = 0; i < elementNames.length; i++) { + elementNames[i] = elementName + i; + values[i] = value + i; + } + + Restriction dto = q() + .eq(elementNames[0], values[0]) + .or().gt(elementNames[1], values[1]) + .or().ew(elementNames[2], values[2]) + .or().lt(elementNames[3], values[3]) + .criteria().getRestriction(); + assertTrue( "Restriction is " + dto.getClass().getName(), dto instanceof Or ); + Or or = (Or) dto; + Restriction[] dtos = or.getRestrictions().toArray(new Restriction[]{}); + checkRestriction(dtos[0], RestrictionName.EQUALS, elementName + "0", value + "0"); + checkRestriction(dtos[1], RestrictionName.GREATER, elementName + "1", value + "1"); + checkRestriction(dtos[2], RestrictionName.ENDS_WITH, elementName + "2", value + "2"); + checkRestriction(dtos[3], RestrictionName.LESS, elementName + "3", value + "3"); + } + + @Test + public void testAssociated() throws Exception { + /* Following request mean is : + * Looking for any product which price is between 15 and 25, + * and name starts with 'Paint', + * and with an associated category which name is 'Hardware' + */ + + Restriction dto = q() + .bw( "Product.price", "15", "25") + .sw( "Product.name", "Paint") + .associated( "Product.category" ) + .eq( "Category.name", "Hardware" ) + .criteria().getRestriction(); + + assertTrue( "Restriction is " + dto.getClass().getName(), dto instanceof AssociatedRestriction ); + AssociatedRestriction ass = (AssociatedRestriction) dto; + Restriction embedded = ass.getRestriction(); + assertTrue( "Restriction is " + dto.getClass().getName(), embedded instanceof Equals ); + checkRestriction(embedded, RestrictionName.EQUALS, "Category.name", "Hardware"); + assertEquals( "Product.category", ass.getElement().getName() ); + Restriction parentRestriction = ass.getParentRestrictionDto(); + assertTrue( "Restriction is " + dto.getClass().getName(), parentRestriction instanceof And ); + And and = (And) parentRestriction; + Restriction[] dtos = and.getRestrictions().toArray(new Restriction[]{}); + assertTrue( dtos[0] instanceof Between ); + checkRestriction(dtos[1], RestrictionName.STARTS_WITH, "Product.name", "Paint"); + } + + @Test + public void testXML() throws Exception { + Criteria criteria = q().bw(elementName, "from", "to").criteria(); + + // Serialize + String xml = Criteria.toXML(criteria); + log.debug("[XML] " + xml); + assertNotNull(xml); + + // Deserialize + criteria = Criteria.fromXML(xml); + assertNotNull(criteria); + } + + /* + * -============ private test utils operations ============- + */ + private final static Search q() { + return Search.query(); + } + + private void checkSearch( Search search, RestrictionName name ) throws Exception { + Restriction dto = search.criteria().getRestriction(); + checkRestriction( dto, name, elementName, value ); + } + + private void checkRestriction(Restriction dto, RestrictionName name, + String element, String value) throws Exception { + assertTrue( dto instanceof BinaryOperator ); + BinaryOperator bop = (BinaryOperator) dto; + assertEquals( name, dto.getName() ); + assertEquals( element, bop.getElement().getName() ); + assertEquals( value, bop.getValue() ); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/WikittyUtilTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/WikittyUtilTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/api/WikittyUtilTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sharengo.wikitty.test.api; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.fail; + +import java.math.BigDecimal; +import java.util.*; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyUtil; + +/** + * + * @author poussin + */ +public class WikittyUtilTest extends AbstractTestApi { + + + static private Log log = LogFactory.getLog(WikittyUtilTest.class); + + /** + * Test of normalizeVersion method, of class WikittyUtil. + */ + @Test + public void testNormalizeVersion() { + { + String version = null; + String expResult = "0"; + String result = WikittyUtil.normalizeVersion(version); + assertEquals(expResult, result); + } + { + String version = ""; + String expResult = "0"; + String result = WikittyUtil.normalizeVersion(version); + assertEquals(expResult, result); + } +} + + /** + * Test of versionEquals method, of class WikittyUtil. + */ + @Test + public void testVersionEquals() { + { + String v1 = "0.4"; + String v2 = "0.4"; + boolean expResult = true; + boolean result = WikittyUtil.versionEquals(v1, v2); + assertEquals(expResult, result); + } + { + String v1 = "0.4.0"; + String v2 = "0.4"; + boolean expResult = false; + boolean result = WikittyUtil.versionEquals(v1, v2); + assertEquals(expResult, result); + } + } + + /** + * Test of versionGreaterThan method, of class WikittyUtil. + */ + @Test + public void testVersionGreaterThan() { + String v1 = "4.5"; + String v2 = "4.4"; + boolean expResult = true; + boolean result = WikittyUtil.versionGreaterThan(v1, v2); + assertEquals(expResult, result); + } + + /** + * Test of incrementMinorRevision method, of class WikittyUtil. + */ + @Test + public void testIncrementMinorRevision() { + { + String v = ""; + String expResult = "0.1"; + String result = WikittyUtil.incrementMinorRevision(v); + assertEquals(expResult, result); + } + { + String v = "0"; + String expResult = "0.1"; + String result = WikittyUtil.incrementMinorRevision(v); + assertEquals(expResult, result); + } + { + String v = "1.0"; + String expResult = "1.1"; + String result = WikittyUtil.incrementMinorRevision(v); + assertEquals(expResult, result); + } + { + String v = "1.4"; + String expResult = "1.5"; + String result = WikittyUtil.incrementMinorRevision(v); + assertEquals(expResult, result); + } + { + String v = "1.9"; + String expResult = "1.10"; + String result = WikittyUtil.incrementMinorRevision(v); + assertEquals(expResult, result); + } + } + + /** + * Test la difference de temps entre differente methode d'increment de version + * qui est sous forme texte. + * + * <li> parsing Integer + 1 (757ms / 3 millions d'appels) + * <li> switch sur les caracteres (419ms / 3 millions d'appels) + * <li> appel d'une methode d'increment (462ms / 3 millions d'appels) + */ + @Test + public void testPerfIncrementMinorRevision() { + int MAX = 3000000; + String v = "0"; + + long time = System.currentTimeMillis(); + for (int cpt=0; cpt < MAX; cpt++) { + int i = Integer.parseInt(v) + 1; + v = String.valueOf(i); + } + long timeParse = System.currentTimeMillis() - time; + + v = "0"; + time = System.currentTimeMillis(); + for (int cpt=0; cpt < MAX; cpt++) { + v = inc(v); + } + long timeCall = System.currentTimeMillis() - time; + + v = "0"; + time = System.currentTimeMillis(); + for (int cpt=0; cpt < MAX; cpt++) { + char [] c = v.toCharArray(); + boolean retenue = true; + for (int i=c.length-1; retenue && i>=0; i--) { + switch(c[i]) { + case '0': c[i] = '1'; retenue = false; break; + case '1': c[i] = '2'; retenue = false; break; + case '2': c[i] = '3'; retenue = false; break; + case '3': c[i] = '4'; retenue = false; break; + case '4': c[i] = '5'; retenue = false; break; + case '5': c[i] = '6'; retenue = false; break; + case '6': c[i] = '7'; retenue = false; break; + case '7': c[i] = '8'; retenue = false; break; + case '8': c[i] = '9'; retenue = false; break; + default: c[i] = '0'; break; + } + } + if (retenue) { + v = "1" + String.valueOf(c); + } else { + v = String.valueOf(c); + } + } + long timeSwitch = System.currentTimeMillis() - time; + + log.info("Inc parse: " + timeParse + " call: "+ timeCall + " switch: " + timeSwitch + " (" + v + ")"); + } + + protected String inc(String v) { + char [] c = v.toCharArray(); + boolean retenue = true; + for (int i=c.length-1; retenue && i>=0; i--) { + switch(c[i]) { + case '0': c[i] = '1'; retenue = false; break; + case '1': c[i] = '2'; retenue = false; break; + case '2': c[i] = '3'; retenue = false; break; + case '3': c[i] = '4'; retenue = false; break; + case '4': c[i] = '5'; retenue = false; break; + case '5': c[i] = '6'; retenue = false; break; + case '6': c[i] = '7'; retenue = false; break; + case '7': c[i] = '8'; retenue = false; break; + case '8': c[i] = '9'; retenue = false; break; + default: c[i] = '0'; break; + } + } + if (retenue) { + v = "1" + String.valueOf(c); + } else { + v = String.valueOf(c); + } + return v; + } + + /** + * Test of incrementMajorRevision method, of class WikittyUtil. + */ + @Test + public void testIncrementMajorRevision() { + { + String v = ""; + String expResult = "1.0"; + String result = WikittyUtil.incrementMajorRevision(v); + assertEquals(expResult, result); + } + { + String v = "0"; + String expResult = "1.0"; + String result = WikittyUtil.incrementMajorRevision(v); + assertEquals(expResult, result); + } + { + String v = "1.5"; + String expResult = "2.0"; + String result = WikittyUtil.incrementMajorRevision(v); + assertEquals(expResult, result); + } + } + + /** + * Test of toBigDecimal method, of class WikittyUtil. + */ + @Test + public void testToBigDecimal() { + Object value = null; + BigDecimal expResult = new BigDecimal(0); + BigDecimal result = WikittyUtil.toBigDecimal(value); + assertEquals(expResult, result); + } + + /** + * Test of toBoolean method, of class WikittyUtil. + */ + @Test + public void testToBoolean() { + Object value = null; + boolean expResult = false; + boolean result = WikittyUtil.toBoolean(value); + assertEquals(expResult, result); + } + + /** + * Test of toString method, of class WikittyUtil. + */ + @Test + public void testToString() { + Object value = null; + String expResult = null; + String result = WikittyUtil.toString(value); + assertEquals(expResult, result); + } + + /** + * Test of toDate method, of class WikittyUtil. + */ + @Test + public void testToDate() { + Object value = null; + Date expResult = null; + Date result = WikittyUtil.toDate(value); + assertEquals(expResult, result); + } + + /** + * Test of toWikitty method, of class WikittyUtil. + */ + @Test + public void testToWikitty() { + Object value = null; + String expResult = null; + String result = WikittyUtil.toWikitty(value); + assertEquals(expResult, result); + } + + /** + * Test of toList method, of class WikittyUtil. + */ + @Test + public void testToList() { + Object value = null; + Class clazz = Object.class; + List<Object> expResult = null; + List<Object> result = WikittyUtil.toList(value, clazz); + assertEquals(expResult, result); + } + + /** + * Test of getClass method, of class WikittyUtil. + */ + @Test + public void testGetClass() { + Object value = null; + Class expResult = null; + Class result = WikittyUtil.getClass(value); + assertEquals(expResult, result); + } + + /** + * Test of cast method, of class WikittyUtil. + */ + @Test + public void testCast() { + { + Object obj = null; + Class<Object> clazz = null; + Object expResult = null; + Object result = WikittyUtil.cast(obj, clazz); + assertEquals(expResult, result); + } + { + Object obj = "Toto"; + Class<Object> clazz = Object.class; + Object expResult = "Toto"; + Object result = WikittyUtil.cast(obj, clazz); + assertEquals(expResult, result); + } + { + Object obj = new Object(); + Class<String> clazz = String.class; + Object expResult = obj; + try { + Object result = WikittyUtil.cast(obj, clazz); + fail("cast object to string !!!"); + } catch (Exception eee) { + // ok + } + } + } + + @Test + public void testUID() throws Exception { + for ( int i = 0; i < 8; i++ ) { + String uid = WikittyUtil.genUID(); + log.info("uid = " + uid); + } + } + + @Test + public void testWikittyExtensionBuild() { + String extName = "Produit"; + + LinkedHashMap<String, FieldType> fields = WikittyUtil.buildFieldMapExtension( + "String name", + "Numeric amount", + "Date buildDate"); + + assertNotNull( fields.get("name") ); + assertNotNull( fields.get("amount") ); + assertNotNull( fields.get("buildDate") ); + + WikittyExtension ext = new WikittyExtension(extName, "1", null, fields); + + assertNotNull( ext.getFieldType("name") ); + assertNotNull( ext.getFieldType("amount") ); + assertNotNull( ext.getFieldType("buildDate") ); + } + + + /** + * test newInstance method, and verify that we can configure implementation + * for specifique interface + * @throws Exception + */ + /* Deprecated operation no more tested + @Test + public void testNewInstance() throws Exception { + Label label = WikittyUtil.newInstance(Label.class, null); + assertNull(label); + + WikittyUtil.interfaceToClass.put(Label.class, MonLabel.class); + label = WikittyUtil.newInstance(Label.class, null); + assertNull(label); + } + */ + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/AbstractTestConformance.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/AbstractTestConformance.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/AbstractTestConformance.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,155 @@ +package org.sharengo.wikitty.test.conform; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +import junit.framework.Assert; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.runner.RunWith; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.FieldType.TYPE; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:META-INF/spring/wikitty-conformance-test.xml") +public abstract class AbstractTestConformance { + + public static final String EXTNAME = "wikittyExt"; + + protected final static Log log = LogFactory.getLog(AbstractTestConformance.class); + + public static final WikittyExtension EXT_TEST = + createExtension(EXTNAME, + createType(TYPE.STRING, 0, 1), + createType(TYPE.NUMERIC, 1, 1), + createType(TYPE.DATE, 1, 1) + ); + + @Autowired + protected WikittyService ws ; + + public WikittyService getWikittyService() { + return ws; + } + + public void setWikittyService(WikittyService wikittyService) { + this.ws = wikittyService; + } + + + protected static FieldType createType( TYPE type, int lower, int upper ) { + FieldType fieldType = new FieldType(type, lower, upper); + return fieldType; + } + + protected static Wikitty createBasicWikitty() { + return createWikitty( EXT_TEST ); + } + + protected static Wikitty createWikitty( WikittyExtension... extensions ) { + Wikitty w = new Wikitty(); + for ( WikittyExtension ext : extensions ) { + w.addExtension( ext ); + } + return w; + } + + protected static WikittyExtension createExtension( String extName, FieldType... types ) { + LinkedHashMap<String, FieldType> fieldsMap = new LinkedHashMap<String, FieldType>(); + for ( int i = 0; i < types.length; i++ ) { + fieldsMap.put( "fieldName" + i, types[i] ); + } + return new WikittyExtension(extName, "1", null, fieldsMap); + } + + protected static SimpleDateFormat dateFormater = new SimpleDateFormat("d/M/y"); + protected static String date( String dateTestFormat ) { + try { + return WikittyUtil.solrDateFormat.format( + dateTestFormat == null || dateTestFormat.isEmpty() + ? new Date() : dateFormater.parse(dateTestFormat) + ); + } catch (ParseException e) { + Assert.fail( "Error parsing date : " + dateTestFormat ); + e.printStackTrace(); + return null; + } + } + protected static String date( Date date ) { + return WikittyUtil.solrDateFormat.format( date ); + } + + protected static ArrayList<Wikitty> createSampleWikitty( WikittyService ws ) { + ArrayList<Wikitty> result = new ArrayList<Wikitty>(); + String[] wValues = new String[] { + // wikitty[ 0 ] + "fieldName0 = table," + + "fieldName1 = 003300," + + "fieldName2 = " + date("23/01/1982"), + + // wikitty[ 1 ] + "fieldName0 = chaise," + + "fieldName1 = 113311," + + "fieldName2 = " + date("26/09/2009"), + + // wikitty[ 2 ] + "fieldName0 = bureau," + + "fieldName1 = 223322," + + "fieldName2 = " + date("25/12/2029") + }; + for ( String wValue : wValues ) { + Wikitty w = createWikitty( wValue, EXTNAME, EXT_TEST ); + result.add( w ); + } + ws.store(result); + return result; + } + + + + public static Wikitty createWikitty( String values, String defaultExtName, WikittyExtension... exts ) { + Wikitty w = new Wikitty(); + for ( WikittyExtension ext : exts ) w.addExtension(ext); + for( Entry<String, String> keyValuePair : getKeyPairs(values) ) { + String[] s = keyValuePair.getKey().split("\\."); + int i = 0; + String fieldName = null, extName = null; + if ( s.length > 1 ) { + fieldName = s[1].trim(); + extName = s[0].trim(); + } + else { + fieldName = s[0].trim(); + extName = defaultExtName; + } + w.setField(extName, fieldName, keyValuePair.getValue()); + } + return w; + } + + protected static Iterable<Entry<String, String>> getKeyPairs(String values) { + LinkedHashMap<String, String> keyPairs = new LinkedHashMap<String, String>(); + for ( String keyValuePair : values.split(",") ) { + String[] l = keyValuePair.split("="); + String key = l[0].trim(); + String value = l.length > 1 ? l[1].trim() : null; + keyPairs.put(key, value); + } + return keyPairs.entrySet(); + } + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/CommonTestHelper.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/CommonTestHelper.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/CommonTestHelper.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,84 @@ +package org.sharengo.wikitty.test.conform; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.LinkedHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.FieldType.TYPE; +import org.springframework.beans.factory.annotation.Autowired; + +public class CommonTestHelper { + + @Autowired + protected WikittyService ws; + + public CommonTestHelper(WikittyService ws) { + this.ws = ws; + } + + public void setWikittyService( WikittyService ws ) { + this.ws = ws; + } + + public static final String EXTNAME = "wikittyExt"; + + protected final static Log log = LogFactory.getLog(CommonTestHelper.class); + + public static final WikittyExtension EXT_TEST = + createExtension(EXTNAME, + createType(TYPE.STRING, 0, 1), + createType(TYPE.NUMERIC, 1, 1), + createType(TYPE.DATE, 1, 1) + ); + + + protected static FieldType createType( TYPE type, int lower, int upper ) { + FieldType fieldType = new FieldType(type, lower, upper); + return fieldType; + } + + protected static Wikitty createBasicWikitty() { + return createWikitty( EXT_TEST ); + } + + protected static Wikitty createWikitty( WikittyExtension... extensions ) { + Wikitty w = new Wikitty(); + for ( WikittyExtension ext : extensions ) { + w.addExtension( ext ); + } + return w; + } + + @Deprecated + /** + * Deprecated : use ExtensionFactory instead + */ + protected static WikittyExtension createExtension( String extName, FieldType... types ) { + LinkedHashMap<String, FieldType> fieldsMap = new LinkedHashMap<String, FieldType>(); + for ( int i = 0; i < types.length; i++ ) { + fieldsMap.put( "fieldName" + i, types[i] ); + } + return new WikittyExtension(extName, "1", null, fieldsMap); + } + + public static final SimpleDateFormat dateFormater = new SimpleDateFormat("d/M/y"); + public static String date( String dateTestFormat ) throws ParseException { + return WikittyUtil.solrDateFormat.format( + dateTestFormat == null || dateTestFormat.isEmpty() + ? new Date() : dateFormater.parse(dateTestFormat) + ); + } + public static String date( Date date ) { + return WikittyUtil.solrDateFormat.format( date ); + } + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/SearchApiTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/SearchApiTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/SearchApiTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,105 @@ +package org.sharengo.wikitty.test.conform; + +import static junit.framework.Assert.assertEquals; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Test; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.ExtensionFactory; +import org.sharengo.wikitty.PagedResult; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.FieldType.TYPE; +import org.sharengo.wikitty.search.Search; + +public class SearchApiTest extends AbstractTestConformance { + + /* + * FIXME Will contains all conformance tests to the search features. + */ + + public void testSearch() throws Exception { + String value = ""; + Criteria criteria = + Search.query() + .eq( "element", value ) + .gt( "element2", value ) + .or() + .lt( "element3", value ) + .criteria(); + /* + * is equivalent to : + * ( element = value ) AND ( ( element2 > value ) OR ( element3 < value ) ) + */ + } + + @Test + public void testSearch2() throws Exception { + WikittyExtension ext = ExtensionFactory.create("testExt", "1") + .addField("name", TYPE.STRING) + .addField("age", TYPE.NUMERIC) + .extension(); + List<Wikitty> wikitties = new LinkedList<Wikitty>(); + + Wikitty w = new Wikitty(); + w.addExtension(ext); + w.setField(ext.getName(), "name", "Guillaume"); + w.setField(ext.getName(), "age", "27"); + wikitties.add( w ); + + w = new Wikitty(); + w.addExtension(ext); + w.setField(ext.getName(), "name", "Toto"); + w.setField(ext.getName(), "age", "125"); + wikitties.add( w ); + + ws.store(wikitties); + + Criteria criteria = Search.query() + .eq("testExt.name", "Guillaume") + .criteria(); + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + List<Wikitty> found = result.getAll(); + assertEquals(1, found.size()); + log.info( found.get(0).getFieldAsString(ext.getName(), "name") ); + + criteria = Search.query() + .eq("testExt.age", "125") + .criteria(); + result = ws.findAllByCriteria(criteria); + found = result.getAll(); + assertEquals(1, found.size()); + log.info( found.get(0).getFieldAsString(ext.getName(), "name") ); + + criteria = Search.query() + .gt("testExt.age", "10") + .criteria(); + result = ws.findAllByCriteria(criteria); + found = result.getAll(); + assertEquals(2, found.size()); + log.info( found.get(0).getFieldAsString(ext.getName(), "name") ); + log.info( found.get(1).getFieldAsString(ext.getName(), "name") ); + + Wikitty exemple = new Wikitty(); + exemple.addExtension(ext); + exemple.setField(ext.getName(), "name", "Guillaume"); + exemple.setField(ext.getName(), "age", "27"); + result = ws.findAllByCriteria( Search.query(exemple).criteria() ); + found = result.getAll(); + assertEquals(1, found.size()); + log.info( found.get(0).getFieldAsString(ext.getName(), "name") ); + + exemple = new Wikitty(); + exemple.addExtension(ext); + exemple.setField(ext.getName(), "name", "Guillaume"); + exemple.setField(ext.getName(), "age", "125"); + result = ws.findAllByCriteria( Search.query(exemple).criteria() ); + found = result.getAll(); + assertEquals(0, found.size()); + // log.info( found.get(0).getFieldAsString(ext.getName(), "name") ); + + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/StorageTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/StorageTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/conform/StorageTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,440 @@ +package org.sharengo.wikitty.test.conform; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.PagedResult; +import org.sharengo.wikitty.Tree; +import org.sharengo.wikitty.TreeNode; +import org.sharengo.wikitty.TreeNodeImpl; +import org.sharengo.wikitty.UpdateResponse; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyException; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.search.Search; + +public class StorageTest extends AbstractTestConformance { + + protected final static Log log = LogFactory.getLog(StorageTest.class); + + @Test + public void testStoreRestoreBasics() throws Exception { + Wikitty w = createBasicWikitty(); + String id = w.getId(); + ws.store( w ); + w = ws.restore( id ); + assertTrue( w.hasExtension(EXTNAME) ); + for ( int i = 0; i < 3; i++ ) { + assertTrue( w.hasField(EXTNAME, "fieldName" + i) ); + } + } + + @Test + public void testExtensionMethod() throws Exception { + ws.storeExtension(Arrays.asList(EXT_TEST)); + List<String> extIds = ws.getAllExtensionIds(); + log.debug("extIds: " + extIds); + assertEquals(1, extIds.size()); + WikittyExtension ext = ws.restoreExtension(extIds.get(0)); + assertEquals(EXT_TEST.getName(), ext.getName()); + assertEquals(EXT_TEST.getVersion(), ext.getVersion()); + assertEquals(EXT_TEST, ext); + } + + @Test + public void testStoreRestoreLists() throws Exception { + List<Wikitty> wikitties = new ArrayList<Wikitty>(); + List<String> ids = new ArrayList<String>(); + String[] wValues = new String[] { + // wikitty[ 0 ] + "fieldName0 = hello," + + "fieldName1 = 123456," + + "fieldName2 = " + date("23/01/1982"), + + // wikitty[ 1 ] + "fieldName0 = Bonzai !," + + "fieldName1 = 111111," + + "fieldName2 = " + date("26/09/2009"), + + // wikitty[ 2 ] + "fieldName0 = ho ho ho !," + + "fieldName1 = 987654," + + "fieldName2 = " + date("25/12/2029") + }; + for ( String wValue : wValues ) { + Wikitty w = createWikitty( wValue, EXTNAME, EXT_TEST ); + wikitties.add( w ); + ids.add( w.getId() ); + } + ws.store(wikitties); + + wikitties = ws.restore(ids); + int wIndex = 0; + for ( String wValue : wValues ) { + Wikitty w = wikitties.get(wIndex); + int i = 0; + for( Entry<String, String> keyValuePair : getKeyPairs(wValue) ) { + String fieldName = "fieldName" + i; + assertEquals(fieldName, keyValuePair.getKey()); + String errorMsg = "Error check field '" + fieldName + "' on wikitty[" + i + "]"; + switch( i ) { + case 0: // check fieldName0 + assertEquals( errorMsg, + keyValuePair.getValue(), w.getFieldAsString(EXTNAME, fieldName) ); + break; + case 1: // check fieldName1 + assertEquals( errorMsg, + Integer.parseInt(keyValuePair.getValue()), + w.getFieldAsInt(EXTNAME, fieldName) ); + break; + case 2: // check fieldName2 + assertEquals( errorMsg, + WikittyUtil.solrDateFormat.parseObject(keyValuePair.getValue()), + w.getFieldAsDate(EXTNAME, fieldName) ); + break; + default: + fail( "this structure should only get 3 elements, unexpected : " + keyValuePair.getKey() ); + } + i++; + } + wIndex++; + } + } + + @Test + public void testStoreRestoreNullEmpty() throws Exception { + Wikitty w = null; + // should be ignored (?) + try { + ws.store( w ); + fail("store(null) Must throw an exception !"); + } catch (Exception e) { + // OK ! + } + + w = new Wikitty(); + String id = w.getId(); + ws.store( w ); + w = ws.restore(id); + assertEquals( id, w.getId() ); + } + + @Test + public void testFieldConstraint() throws Exception { + WikittyExtension ext = new WikittyExtension("TestConstraint", "1", null, + WikittyUtil.buildFieldMapExtension( + "String id not null", + "String ext[0-n] unique", + "String other[0-n] unique not null" + )); + + ws.storeExtension(Arrays.asList(ext)); + Wikitty w = new Wikitty(); + w.addExtension(ext); + + try { + ws.store(w); + assertFalse("not null contraint don't work on String", true); + } catch (WikittyException eee) { + eee.printStackTrace(); + // ok id must not be null + } + + w.setField("TestConstraint", "id", "toto"); + try { + ws.store(w); + assertFalse("not null contraint don't work in Collection", true); + } catch (WikittyException eee) { + eee.printStackTrace(); + // ok id must not be null + } + + w.addToField("TestConstraint", "other", "titi"); + ws.store(w); + + w.addToField("TestConstraint", "ext", "tata"); + w.addToField("TestConstraint", "ext", "titi"); + ws.store(w); + + Wikitty w2 = ws.restore(w.getId()); + w2.addToField("TestConstraint", "ext", "tata"); // tata ne doit pas s'ajouter + w2.addToField("TestConstraint", "ext", "toto"); + + ws.store(w2); + Wikitty w3 = ws.restore(w.getId()); + + HashSet set = new HashSet(Arrays.asList("tata", "titi", "toto")); + assertEquals(set, w3.getFieldAsSet("TestConstraint", "ext", String.class)); + } + + @Test + // not in StorageTest because InMemory don't support find + public void testStoreFindAll() throws Exception { + + // create some wikitty to permit search test + List<Wikitty> wikitties = new ArrayList<Wikitty>(); + String[] wValues = new String[] { + // wikitty[ 0 ] + "fieldName0 = table," + + "fieldName1 = 003309," + + "fieldName2 = " + date("23/01/1982"), + + // wikitty[ 1 ] + "fieldName0 = chaise," + + "fieldName1 = 003309," + + "fieldName2 = " + date("26/09/2009"), + + // wikitty[ 2 ] + "fieldName0 = bureau," + + "fieldName1 = 223322," + + "fieldName2 = " + date("25/12/2029") + }; + for ( String wValue : wValues ) { + Wikitty w = createWikitty( wValue, EXTNAME, EXT_TEST ); + wikitties.add( w ); + } + ws.store(wikitties); + + // search test + Wikitty w = new Wikitty(); + w.addExtension(EXT_TEST); + w.setField(EXT_TEST.getName(), "fieldName1", "003309"); + Criteria criteria = Search.query(w).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + PagedResult<Wikitty> resultFind = ws.findAllByCriteria(criteria); + + assertEquals(2, resultFind.size()); + assertEquals(wikitties.subList(0, 2), resultFind.getAll()); + } + + @Test + // not in StorageTest because InMemory don't support find + public void testStoreFindAllFacet() throws Exception { + + // create some wikitty to permit search test + List<Wikitty> wikitties = new ArrayList<Wikitty>(); + String[] wValues = new String[] { + // wikitty[ 0 ] + "fieldName0 = table," + + "fieldName1 = 663300," + + "fieldName2 = " + date("23/01/1982"), + + // wikitty[ 1 ] + "fieldName0 = chaise," + + "fieldName1 = 663300," + + "fieldName2 = " + date("26/09/2009"), + + // wikitty[ 2 ] + "fieldName0 = bureau," + + "fieldName1 = 223322," + + "fieldName2 = " + date("25/12/2029") + }; + for ( String wValue : wValues ) { + Wikitty w = createWikitty( wValue, EXTNAME, EXT_TEST ); + wikitties.add( w ); + } + ws.store(wikitties); + + // search test + Wikitty w = new Wikitty(); + w.addExtension(EXT_TEST); + w.setField(EXT_TEST.getName(), "fieldName1", "663300"); + Criteria criteria = Search.query(w).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS) + .addFacetField(EXT_TEST.getName()+".fieldName0") + .addFacetField(EXT_TEST.getName()+".fieldName1"); + PagedResult<Wikitty> resultFind = ws.findAllByCriteria(criteria); + + List<String> facetNames = new ArrayList<String>(resultFind.getFacetNames()); + Collections.sort(facetNames); + assertEquals(Arrays.asList(EXT_TEST.getName()+".fieldName0", + EXT_TEST.getName()+".fieldName1"), facetNames); + + // with must have 2 topic: table and chaise + assertEquals(2, resultFind.getTopic(EXT_TEST.getName()+".fieldName0").size()); + // with must have 1 topic: 663300 + assertEquals(1, resultFind.getTopic(EXT_TEST.getName()+".fieldName1").size()); + } + + @Test + // not in StorageTest because InMemory don't support find + public void testStoreFindDelete() throws Exception { + + // create some wikitty to permit search test + List<Wikitty> wikitties = new ArrayList<Wikitty>(); + String[] wValues = new String[] { + // wikitty[ 0 ] + "fieldName0 = table," + + "fieldName1 = 003301," + + "fieldName2 = " + date("23/01/1982"), + + // wikitty[ 1 ] + "fieldName0 = chaiseICI," + + "fieldName1 = 113312," + + "fieldName2 = " + date("26/09/2009"), + + // wikitty[ 2 ] + "fieldName0 = bureau," + + "fieldName1 = 223323," + + "fieldName2 = " + date("25/12/2029") + }; + for ( String wValue : wValues ) { + Wikitty w = createWikitty( wValue, EXTNAME, EXT_TEST ); + wikitties.add( w ); + } + Map<String, String> oldIdVersion = new HashMap<String, String>(); + for( Wikitty w : wikitties ) { + oldIdVersion.put(w.getId(), w.getVersion()); + } + UpdateResponse response = ws.store(wikitties); + for (Wikitty w : wikitties) { + response.update(w); + String v1 = w.getVersion(); + String v2 = oldIdVersion.get( w.getId() ); + assertNotNull( v1 ); + assertNotNull( v2 ); + assertTrue(WikittyUtil.versionGreaterThan(v1, v2)); + } + + // search test + Wikitty w = new Wikitty(); + w.addExtension(EXT_TEST); + w.setField(EXT_TEST.getName(), "fieldName0", "chaiseICI"); + Criteria criteria = Search.query(w).criteria(); + Wikitty resultFind = ws.findByCriteria(criteria); + + Wikitty wikittySource = wikitties.get(1); + assertEquals(w.getFieldAsString(EXT_TEST.getName(), "fieldName0"), + resultFind.getFieldAsString(EXT_TEST.getName(), "fieldName0")); + + assertEquals(wikittySource.getId(), resultFind.getId()); + // test equals implantation method + assertEquals(wikittySource, resultFind); + + assertEquals(wikittySource.getFieldAsString(EXT_TEST.getName(), "fieldName0"), + resultFind.getFieldAsString(EXT_TEST.getName(), "fieldName0")); + assertEquals(wikittySource.getFieldAsString(EXT_TEST.getName(), "fieldName1"), + resultFind.getFieldAsString(EXT_TEST.getName(), "fieldName1")); + assertEquals(wikittySource.getFieldAsString(EXT_TEST.getName(), "fieldName2"), + resultFind.getFieldAsString(EXT_TEST.getName(), "fieldName2")); + + + ws.delete(wikittySource.getId()); + Wikitty deletedObject = ws.restore(wikittySource.getId()); + assertNotNull(deletedObject.getDeleteDate()); + } + + @Test + // not in StorageTest because InMemory don't support addLabel + public void testStoreAndLabel() throws Exception { + + // create some wikitty to permit search test + List<Wikitty> wikitties = createSampleWikitty(ws); + long ts = new Date().getTime(); + + // labelisation test + Wikitty w1 = wikitties.get(0); + ws.addLabel(w1.getId(), "titi"+ts); + ws.addLabel(w1.getId(), "toto"+ts); + + Wikitty w2 = wikitties.get(1); + ws.addLabel(w2.getId(), "tata"+ts); + ws.addLabel(w2.getId(), "titi"+ts); + + Wikitty w3 = wikitties.get(2); + ws.addLabel(w3.getId(), "tutu"+ts); + ws.addLabel(w3.getId(), "titi"+ts); + + Wikitty wt = ws.findByLabel("toto"+ts ); + + assertEquals(w1, wt); + + Set<String> labels = ws.findAllAppliedLabels(w2.getId()); + + assertEquals(new HashSet(Arrays.asList("tata"+ts, "titi"+ts)), labels); + } + + @Test + public void testStoreAndClassification() throws Exception { + // create some wikitty to permit search test + List<Wikitty> wikitties = createSampleWikitty(ws); + List<Wikitty> wikittyNodes = new ArrayList<Wikitty>(); + + TreeNodeImpl root = new TreeNodeImpl(); + wikittyNodes.add(root.getWikitty()); + root.setName("MyCategoryRoot"); + for ( int i = 0; i < 3; i++ ) { + TreeNodeImpl leaf = new TreeNodeImpl(); + wikittyNodes.add( leaf.getWikitty() ); + leaf.setName( "cat-"+i ); + leaf.setParent( root.getWikittyId() ); + // root.addChild( leaf.getWikittyId() ); + + for ( int j = 0; j < 5; j++ ) { + TreeNodeImpl subLeaf = new TreeNodeImpl(); + subLeaf.setName( "subcat-"+i+"-"+j ); + subLeaf.setParent( leaf.getWikittyId() ); + wikittyNodes.add( subLeaf.getWikitty() ); + // leaf.addChild( subLeaf.getWikittyId() ); + } + } + ws.store(wikittyNodes); // store treeNodes. + + Wikitty table = wikitties.get(0); + Wikitty chaise = wikitties.get(1); + Wikitty bureau = wikitties.get(2); + + assign( chaise, root, "cat-1/subcat-1-4" ); + assign( table, root, "cat-1" ); + assign( bureau, root, "cat-2/subcat-2-4" ); + + Tree t = ws.restoreTree( root.getWikitty().getId() ); + t.getName().equals("MyCategoryRoot"); + + + } + + private void assign(Wikitty wikitty, TreeNodeImpl root, String path) { + String[] nodeNames = path.split("/"); + TreeNodeImpl currentNode = root; + outerloop : for( String nodeName : nodeNames ) { + TreeNodeImpl node = new TreeNodeImpl(); + node.setName(nodeName); + + Criteria criteria = Search.query(node.getWikitty()).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + List<Wikitty> wikitties = ws.findAllByCriteria(criteria).getAll(); + for ( Wikitty child : wikitties ) { + if ( !child.hasExtension(TreeNode.EXT_TREENODE) ) continue; + node = new TreeNodeImpl(child); + if ( node.getName().equals(nodeName) ) { + currentNode = node; + continue outerloop; + } + } + fail( "Unable to find node " + nodeName + " inside " + currentNode.getName() ); + } + currentNode.addChildren( wikitty.getId() ); + ws.store(currentNode.getWikitty()); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/memory/InMemoryStorageTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/memory/InMemoryStorageTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/java/org/sharengo/wikitty/test/memory/InMemoryStorageTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,119 @@ +package org.sharengo.wikitty.test.memory; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.ExtensionFactory; +import org.sharengo.wikitty.PagedResult; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyServiceInMemory; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.FieldType.TYPE; +import org.sharengo.wikitty.search.Search; +import org.sharengo.wikitty.test.api.AbstractTestApi; + +public class InMemoryStorageTest extends AbstractTestApi { + + protected WikittyServiceInMemory wikittyService; + + @Before + public void init() throws Exception { + wikittyService = new WikittyServiceInMemory(); + } + + protected static DateFormat dateFormater = new SimpleDateFormat("dd/MM/yyyy"); + + @Test + public void testFilePersistance() throws Exception { + File tempPersistFile = File.createTempFile(InMemoryStorageTest.class.getName(), ".tmp"); + tempPersistFile.deleteOnExit(); + + wikittyService = new WikittyServiceInMemory( tempPersistFile ); + String extName = "MyExtName"; + WikittyExtension ext = ExtensionFactory.create("MyExtName", "1") + .addField("fieldName0", TYPE.NUMERIC) + .addField("fieldName1", TYPE.NUMERIC) + .addField("fieldName2", TYPE.DATE) + .extension(); + Date date = dateFormater.parse( "30/01/2009" ); + Wikitty w = createWikitty( + "MyExtName.fieldName0 = 123," + + "MyExtName.fieldName1 = 12.3," + + "MyExtName.fieldName2 = " + date(date), + ext + ); + String id = w.getId(); + wikittyService.store(w); + ((WikittyServiceInMemory)wikittyService).saveToPersistenceFile(); + + wikittyService = new WikittyServiceInMemory( tempPersistFile ); + w = wikittyService.restore(id); + assertTrue( w.hasField(extName, "fieldName0") ); + assertEquals( 123, w.getFieldAsInt(extName, "fieldName0") ); + assertTrue( w.hasField(extName, "fieldName1") ); + assertEquals( 12.3f, w.getFieldAsFloat(extName, "fieldName1") ); + assertTrue( w.hasField(extName, "fieldName2") ); + assertEquals( date, w.getFieldAsDate(extName, "fieldName2") ); + } + + private Wikitty createWikitty(String wDef, WikittyExtension... exts) { + Wikitty w = new Wikitty(); + w.addExtension( Arrays.asList(exts) ); + for ( String line : wDef.split(",") ) { + int eqIdx = line.indexOf('='); + String value = line.substring(eqIdx+1).trim(); + String key = eqIdx >= 0 ? line.substring(0, eqIdx): ""; + int dotIdx = key.indexOf('.'); + String fieldName = key.substring(dotIdx+1).trim(); + String extName = dotIdx >= 0 ? key.substring(0, dotIdx): ""; + w.setField(extName, fieldName, value); + } + return w; + } + + @Test + public void testRequire() throws Exception { + WikittyExtension extension = new WikittyExtension("Extension", "1", null, + WikittyUtil.buildFieldMapExtension("String value")); + WikittyExtension extension1 = new WikittyExtension("Extension 1", "1", "Extension", + WikittyUtil.buildFieldMapExtension("String value")); + WikittyExtension extension11 = new WikittyExtension("Extension 11", "1", "Extension 1", + WikittyUtil.buildFieldMapExtension("String value")); + WikittyExtension extension2 = new WikittyExtension("Extension 2", "1", "Extension", + WikittyUtil.buildFieldMapExtension("String value")); + + Wikitty wikitty = createWikitty("Extension.value = 123", + extension, extension1, extension11, extension2); + + Collection<WikittyExtension> result = wikitty.getExtensionDependencies("Extension", true); + assertEquals(3, result.size()); + + result = wikitty.getExtensionDependencies("Extension", false); + assertEquals(2, result.size()); + + result = wikitty.getExtensionDependencies("Extension 1", true); + assertEquals(1, result.size()); + + result = wikitty.getExtensionDependencies("Extension 2", true); + assertEquals(0, result.size()); + } + + + + private String date(Date date) { + return WikittyUtil.solrDateFormat.format(date); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/META-INF/spring/wikitty-conformance-test.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/META-INF/spring/wikitty-conformance-test.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/META-INF/spring/wikitty-conformance-test.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> + + + <bean id="WikittyService" class="org.sharengo.wikitty.WikittyServiceInMemory" /> + + <context:annotation-config/> + <context:component-scan base-package="org.sharengo.wikitty"/> + +</beans> \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/log4j.properties =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/log4j.properties (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-api/src/test/resources/log4j.properties 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,9 @@ +# Appender and Layout +log4j.appender.logConsole=org.apache.log4j.ConsoleAppender +log4j.appender.logConsole.layout=org.apache.log4j.PatternLayout +log4j.appender.logConsole.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n + +# Configuration by components +log4j.rootLogger=ERROR, logConsole +log4j.category.org.sharengo.wikitty=DEBUG +log4j.category.org.apache.solr=DEBUG Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/pom.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/pom.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/pom.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,115 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty-jdbc-impl</artifactId> + + <parent> + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty</artifactId> + <version>1.0.0-alpha-2</version> + </parent> + + <dependencies> + <!-- TEST --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + <!-- COMPILE --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>core-wikitty-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>core-wikitty-solr-impl</artifactId> + <version>${project.version}</version> + </dependency> + <!--dependency> + <groupId>${project.groupId}</groupId> + <artifactId>core-wikitty-test</artifactId> + <version>1.0-SNAPSHOT</version> + </dependency--> + + <!--dependency> + <groupId>com.caucho</groupId> + <artifactId>resin-hessian</artifactId> + </dependency--> + + <!--dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty</artifactId> + <version>6.1.8</version> + </dependency--> + + <!--dependency> + <groupId>xpp3</groupId> + <artifactId>xpp3</artifactId> + <version>1.1.4c</version> + </dependency--> + + <!-- SOLR --> + <dependency> + <groupId>org.apache.solr</groupId> + <artifactId>solr-core</artifactId> + <version>1.3.0</version> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + <scope>runtime</scope> + </dependency> + + <!--dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency--> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>1.1.118</version> + </dependency> + </dependencies> + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>org.sharengo.wikengo.core-wikitty-jdbc-impl</name> + + <description>public api of wikitty</description> + <inceptionYear>2009</inceptionYear> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>jar</packaging> + + <properties> + <maven.test.skip>true</maven.test.skip> + </properties> + + <!--repositories> + + <repository> + <id>sharengo-maven-repository</id> + <name>Repo Sharengo</name> + <url>http://repository.sharengo.org</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </releases> + </repository> + </repositories--> + +</project> + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyExtensionStorageJDBC.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyExtensionStorageJDBC.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyExtensionStorageJDBC.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,383 @@ +package org.sharengo.wikitty.jdbc; + +/* *##% + * Copyright (c) 2009 morin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.*; +import static org.sharengo.wikitty.jdbc.WikittyJDBCUtil.*; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.*; + +/** + * @author morin + * @version $Revision$ + * <p/> + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyExtensionStorageJDBC implements WikittyExtensionStorage { + + /** + * to use log facility, just put in your code: log.info(\"...\"); + */ + static protected Log log = LogFactory.getLog(WikittyExtensionStorageJDBC.class); + /** + * JDBC driver property name + */ + static protected String driver = "jdbc.con.driver"; + /** + * extension_admin table creation query property name + */ + static protected String extAdminCreationQ = "jdbc.queries.creation.extension.admin"; + /** + * extension_data table creation query property name + */ + static protected String extDataCreationQ = "jdbc.queries.creation.extension.data"; + /** + * basic selection without where clause query property name + */ + static protected String selectionQ = "jdbc.queries.select"; + /** + * ordered selection with where clause query property name + */ + static protected String orderedWhereSelectionQ = "jdbc.queries.select.where.order"; + /** + * basic selection with where clause query property name + */ + static protected String whereSelectionQ = "jdbc.queries.select.where"; + /** + * insertion in the admin table query property name + */ + static protected String adminInsertQ = "jdbc.queries.insert.extension.admin"; + /** + * insertion in the data table query property name + */ + static protected String dataInsertQ = "jdbc.queries.insert.extension.data"; + + /** + * admin table name + */ + static protected String adminTable = "extension_admin"; + /** + * data table name + */ + static protected String dataTable = "extension_data"; + + /** + * Properties file + */ + protected Properties conf = loadProperties(); + + public static String WORD_SEPARATOR = "_"; + + class CommandJDBC implements Command { + protected String queries; + + public CommandJDBC(String queries) { + this.queries = queries; + } + } + + /** + * cache for extension key: ext id (extname[extversion]) value: WikittyExtension + */ + protected Map<String, WikittyExtension> extensionCache = + new HashMap<String, WikittyExtension>(); + + /** + * cache for last extension version; key: extName value: extVersion + */ + protected Map<String, String> lastVersion = null; + + public WikittyExtensionStorageJDBC() { + //check if driver ca be loaded + try { + Class.forName(conf.getProperty(driver)); + } catch (ClassNotFoundException eee) { + if (log.isFatalEnabled()) { + log.fatal("Couldn't find the driver!"); + eee.printStackTrace(); + } + throw new WikittyException(eee); + } + + Connection con = null; + //connect + try { + con = getConnection(); + Statement statement = con.createStatement(); + try { + statement.execute(conf.getProperty(extAdminCreationQ)); + statement.execute(conf.getProperty(extDataCreationQ)); + con.commit(); + } catch (SQLException eee) { + con.rollback(); + } + closeConnection(con); + } catch (SQLException eee) { + if (log.isFatalEnabled()) { + log.fatal("Couldn't connect !"); + eee.printStackTrace(); + } + closeConnection(con); + throw new WikittyException(eee); + } + } + + @Override + public List<Command> prepare(WikittyTransaction transaction, + Collection<WikittyExtension> extensions) + throws WikittyException { + Connection con = null; + try { + con = getConnection(); + List<Command> result = new ArrayList<Command>(extensions.size()); + + for (WikittyExtension ext : extensions) { + // extension id is extension name with version + String id = ext.getId(); + Statement statement = con.createStatement(); + //select all the data with the id "id" + ResultSet versionResultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), + COL_VERSION, adminTable, COL_ID, "'" + id + "'")); + StringBuffer batch = new StringBuffer(); + + //if the data is not already recorded + if (!versionResultSet.first()) { + batch.append(String.format(conf.getProperty(adminInsertQ), + ext.getId(), ext.getName(), ext.getVersion(), + ext.getRequires() != null ? "'" + ext.getRequires() + "'" : "null")); + for (int i = 0 ; i < ext.getFieldNames().size() ; i++) { + FieldType type = ext.getFieldType(ext.getFieldNames().get(i)); + batch.append(String.format(conf.getProperty(dataInsertQ), + ext.getId(), ext.getFieldNames().get(i).replace(" ", WORD_SEPARATOR), + type.toDefinition(ext.getFieldNames().get(i).replace(" ", WORD_SEPARATOR)), i)); + } + } else { + log.warn("The extension is found " + id); + } + + result.add(new CommandJDBC(batch.toString())); + } + closeConnection(con); + return result; + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + + } + + @Override + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> extensionStorageCommandList) { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + for (Command command : extensionStorageCommandList) { + CommandJDBC commandJDBC = (CommandJDBC) command; + statement.execute(commandJDBC.queries); + } + con.commit(); + closeConnection(con); + // modification in extension, remove the cache + lastVersion = null; + // nothing to put in result + UpdateResponse result = new UpdateResponse(); + return result; + } catch (SQLException eee) { + closeConnection(con, true); + throw new WikittyException(eee); + } + + } + + @Override + public boolean exists(String id) { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + //select the data with teh id "id" in the admin table + ResultSet resultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), adminTable, + COL_ID, "'" + id + "'")); + boolean result = resultSet.first(); + closeConnection(con); + return result; + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + + } + + @Override + public List<String> getAllExtensionIds() { + Connection con = null; + try { + con = getConnection(); + List<String> result = new ArrayList<String>(); + Statement statement = con.createStatement(); + //get all extensions names and versions + ResultSet resultSet = statement.executeQuery( + String.format(conf.getProperty(selectionQ), + COL_ID, adminTable)); + resultSet.beforeFirst(); + while (resultSet.next()) { + String id = resultSet.getString(COL_ID); + result.add(id); + } + closeConnection(con); + return result; + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + + } + + @Override + public List<WikittyExtension> getAllExtensions(boolean lastVersion) { + Connection con = null; + try { + con = getConnection(); + + List<WikittyExtension> result = new ArrayList<WikittyExtension>(); + Statement statement = con.createStatement(); + //get all extensions names and versions + ResultSet adminResultSet; + if (lastVersion) { + adminResultSet = statement.executeQuery( + String.format(conf.getProperty(selectionQ), "DISTINCT " + COL_NAME, + adminTable)); + adminResultSet.beforeFirst(); + while (adminResultSet.next()) { + String extName = adminResultSet.getString(COL_NAME); + String extVersion = getLastVersion(extName); + String extId = WikittyExtension.computeId(extName, extVersion); + result.add(restore(extId)); + } + } else { + adminResultSet = statement.executeQuery( + String.format(conf.getProperty(selectionQ), COL_ID, + adminTable)); + adminResultSet.beforeFirst(); + while (adminResultSet.next()) { + String extId = adminResultSet.getString(COL_ID); + result.add(restore(extId)); + } + } + closeConnection(con); + return result; + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + } + + /** + * return last version available for specified extension name + * + * @param extName name of extension + * @return last version availble for this version, or null if extension + * doesn't exist + */ + @Override + public String getLastVersion(String extName) { + if (lastVersion == null) { + // create cache for futur call + lastVersion = new HashMap<String, String>(); + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + //get all extensions names and versions + ResultSet resultSet = statement.executeQuery( + String.format(conf.getProperty(selectionQ), + COL_NAME + "," + COL_VERSION, adminTable)); + resultSet.beforeFirst(); + while (resultSet.next()) { + String name = resultSet.getString(COL_NAME); + String version = resultSet.getString(COL_VERSION); + String prevVersion = lastVersion.get(name); + //if the version or this row is greater than the versions of teh already visited rows + if (prevVersion == null || + WikittyUtil.versionGreaterThan(version, prevVersion)) { + lastVersion.put(name, version); + } + } + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + closeConnection(con); + } + String result = lastVersion.get(extName); + return result; + } + + @Override + public WikittyExtension restore(String id) throws WikittyException { + WikittyExtension result = extensionCache.get(id); + if (result == null) { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + //get the data with the id "id" in the admin table + ResultSet adminResultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), "*", + adminTable, COL_ID, "'" + id + "'")); + if (adminResultSet.first()) { + String extName = adminResultSet.getString(COL_NAME); + String extVersion = adminResultSet.getString(COL_VERSION); + String extRequires = adminResultSet.getString(COL_REQUIRES); + LinkedHashMap<String, FieldType> fieldTypes = new LinkedHashMap<String, FieldType>(); + //get the data with the id "id" in the data table + ResultSet dataResultSet = statement.executeQuery( + String.format(conf.getProperty(orderedWhereSelectionQ), "*", + dataTable, COL_ID, "'" + id + "'", COL_FIELDRANK)); + dataResultSet.beforeFirst(); + while (dataResultSet.next()) { + String fieldDef = dataResultSet.getString(COL_FIELDTYPE); + FieldType fieldType = new FieldType(); + String fieldName = WikittyUtil.parseField(fieldDef, fieldType); + fieldTypes.put(fieldName.replace(WORD_SEPARATOR, " "), fieldType); + } + + result = new WikittyExtension(extName, extVersion, extRequires, fieldTypes); + extensionCache.put(id, result); + } + + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(String.format("Can't load extension %s", id), eee); + } + closeConnection(con); + } + return result; + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyJDBCUtil.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyJDBCUtil.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyJDBCUtil.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,188 @@ +/* *##% + * Copyright (c) 2009 morin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty.jdbc; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.IOException; +import java.net.URL; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +/** + * @author morin + * @version $Revision$ + * <p/> + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyJDBCUtil { + + /** + * to use log facility, just put in your code: log.info(\"...\"); + */ + static private Log log = LogFactory.getLog(WikittyJDBCUtil.class); + + /** + * extension list column in the wikitty_admin table + */ + static final public String COL_EXTENSION = "extension_list"; + /** + * requires column in the extension_admin table + */ + static final public String COL_REQUIRES = "requires"; + /** + * version column in the admin tables + */ + static final public String COL_VERSION = "version"; + /** + * id column in all the tables + */ + static final public String COL_ID = "id"; + /** + * name column in the extension_admin table + */ + static final public String COL_NAME = "name"; + /** + * field name column in the data tables + */ + static final public String COL_FIELDNAME = "fieldName"; + /** + * field type column in the extension_data table + */ + static final public String COL_FIELDTYPE = "fieldType"; + /** + * field rank in the extension_data table + */ + static final public String COL_FIELDRANK = "fieldRank"; + /** + * boolean value column in the wikitty_data table + */ + static final public String COL_BOOLEAN_VALUE = "booleanValue"; + /** + * number value column in the wikitty_data table + */ + static final public String COL_NUMBER_VALUE = "numberValue"; + /** + * text value column in the wikitty_data table + */ + static final public String COL_TEXT_VALUE = "textValue"; + /** + * date value column in the wikitty_data table + */ + static final public String COL_DATE_VALUE = "dateValue"; + /** + * deletion date column in wikitty_admin table + */ + static final public String COL_DELETION_DATE = "deletionDate"; + + /** + * host property name + */ + static protected String host = "jdbc.con.host"; + /** + * user name property name + */ + static protected String userName = "jdbc.con.userName"; + /** + * password property name + */ + static protected String password = "jdbc.con.password"; + + /** + * Properties file + */ + protected static Properties conf = loadProperties(); + /** + * location of default config (in class-path) + */ + public static final String CONFIG_FILE = "jdbc.properties"; + + /** + * Loads the properties in the jdbc.properties file. + * + * @return the properties for the connection and the queries + */ + public static Properties loadProperties() { + Properties properties = new Properties(); + try { + //TC-20091115 does not work with webstart, prefer use a nearest classloader + //URL url = ClassLoader.getSystemResource("jdbc.properties"); + URL url = WikittyJDBCUtil.class.getClassLoader().getResource(CONFIG_FILE); + properties.load(url.openStream()); + } catch (Exception eee) { + if (log.isErrorEnabled()) { + log.error("Unable to load property file "+CONFIG_FILE+" for reason "+eee.getMessage(),eee); + } + } + return properties; + } + + /** + * Get a new connection instance (i.e. it opens a new transaction). + * + * @return a new Connection (db transaction) + * @throws SQLException if the connection fails + */ + public static Connection getConnection() throws SQLException { + Connection con = DriverManager.getConnection(conf.getProperty(host), + conf.getProperty(userName), conf.getProperty(password)); + con.setAutoCommit(false); + return con; + } + + /** + * Closes a connection (i.e. transaction). + * If the data are not commited, they will be lost. + * + * @param con the connection to close + */ + public static void closeConnection(Connection con) { + closeConnection(con, false); + } + + /** + * Closes a connection (i.e. transaction). + * If the data are not commited, they will be lost. + * If the option rollback is true, then all the modification made in + * the transaction are canceled. + * + * @param con the connection to close + * @param rollBack if true, all the modification made in + * the transaction are canceled. + */ + public static void closeConnection(Connection con, boolean rollBack) { + try { + if (con != null) { + if (rollBack) { + con.rollback(); + } + con.close(); + } + } catch (SQLException eee) { + if (log.isErrorEnabled()) { + log.error(eee); + } + } + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyServiceJDBC.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyServiceJDBC.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyServiceJDBC.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,84 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty.jdbc; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.*; +import org.sharengo.wikitty.solr.WikittySearchEngineSolr; + +/** + * HBase must have 2 definitions, one for extension and one for wikitty object. + * <p/> + * extension: + * - admin: id, version, ... + * - data: field definition + * <p/> + * wikitty: + * - admin: id, version, extension name and version, ... + * - data: field value + * <p/> + * <p/> + * How to create this definition: + * <li> download and uncompress hbase distribution (from apache repository mirror)</li> + * <li> $hbase-0.19.3/bin/start-hbase.sh</li> + * <li> $hbase-0.19.3/bin/hbase shell</li> + * <li> in the shell + * <li> create 'extension','admin','data'</li> + * <li> create 'wikitty', 'admin', 'data'</li> + * </li> + * + * @author poussin + * @version $Revision$ + * <p/> + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceJDBC extends AbstractWikittyService { + + /** + * to use log facility, just put in your code: log.info(\"...\"); + */ + static private Log log = LogFactory.getLog(WikittyServiceJDBC.class); + + protected WikittySearchEngine searchEngine; + protected WikittyExtensionStorage extensionStorage; + protected WikittyStorage wikittyStorage; + + public WikittyServiceJDBC() { + extensionStorage = new WikittyExtensionStorageJDBC(); + wikittyStorage = new WikittyStorageJDBC(extensionStorage); + searchEngine = new WikittySearchEngineSolr(extensionStorage); + } + + @Override + protected WikittySearchEngine getSearchEngine() { + return searchEngine; + } + + @Override + protected WikittyExtensionStorage getExtensionStorage() { + return extensionStorage; + } + + @Override + protected WikittyStorage getWikittyStorage() { + return wikittyStorage; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyStorageJDBC.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyStorageJDBC.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/main/java/org/sharengo/wikitty/jdbc/WikittyStorageJDBC.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,684 @@ +/* *##% + * Copyright (c) 2009 morin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ +package org.sharengo.wikitty.jdbc; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.*; +import static org.sharengo.wikitty.jdbc.WikittyJDBCUtil.*; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author morin + * @version $Revision$ + * <p/> + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyStorageJDBC implements WikittyStorage { + + /** + * to use log facility, just put in your code: log.info(\"...\"); + */ + static protected Log log = LogFactory.getLog(WikittyStorageJDBC.class); + /** + * JDBC driver property name + */ + static protected String driver = "jdbc.con.driver"; + /** + * wikitty_admin table creation query property name + */ + static protected String wikittyAdminCreationQ = "jdbc.queries.creation.wikitty.admin"; + /** + * wikitty_admin table creation query property name + */ + static protected String wikittyDataCreationQ = "jdbc.queries.creation.wikitty.data"; + /** + * basic selection with where clause query property name + */ + static protected String whereSelectionQ = "jdbc.queries.select.where"; + /** + * not dleeted data selection with where clause query property name + */ + static protected String notDeletedWhereSelectionQ = "jdbc.queries.select.where.notdeleted"; + /** + * insertion in the admin table query property name + */ + static protected String adminInsertQ = "jdbc.queries.insert.wikitty.admin"; + /** + * update in the admin table query property name + */ + static protected String adminUpdateQ = "jdbc.queries.update.wikitty.admin"; + /** + * insertion in the data table query property name + */ + static protected String dataInsertQ = "jdbc.queries.insert.wikitty.data"; + /** + * deletion in the admin table query property name + */ + static protected String adminDeletionQ = "jdbc.queries.delete.wikitty.admin"; + /** + * deletion in the data table query property name + */ + static protected String dataDeletionQ = "jdbc.queries.delete.wikitty.data"; + + /** + * admin table name + */ + static protected String adminTable = "wikitty_admin"; + /** + * data table name + */ + static protected String dataTable = "wikitty_data"; + + /** + * Properties file + */ + protected Properties conf = loadProperties(); + + /** + * used to parse list field from hbase data. ex: extension.fieldname[11/15] + */ + static final private Pattern listFieldPattern = + Pattern.compile("(.*)\\[(\\d+)/(\\d+)\\]"); + + class CommandJDBC implements Command { + + protected boolean toStore; + protected Wikitty wikitty; + protected String queries; + protected String version; + protected String id; + protected Date date; + + public CommandJDBC(String queries, Wikitty wikitty, String version) { + this.queries = queries; + this.toStore = true; + this.wikitty = wikitty; + this.version = version; + } + + public CommandJDBC(String queries, String id, Date date) { + this.queries = queries; + this.toStore = false; + this.id = id; + this.date = date; + } + } + + protected WikittyExtensionStorage extensionStorage; + + public WikittyStorageJDBC(WikittyExtensionStorage extensionStorage) { + this.extensionStorage = extensionStorage; + //check if driver ca be loaded + try { + Class.forName(conf.getProperty(driver)); + } catch (ClassNotFoundException eee) { + if (log.isFatalEnabled()) { + log.fatal("Couldn't find the driver!"); + eee.printStackTrace(); + } + throw new WikittyException(eee); + } + + Connection con = null; + //connect + try { + con = getConnection(); + Statement statement = con.createStatement(); + try { + statement.execute(conf.getProperty(wikittyAdminCreationQ)); + statement.execute(conf.getProperty(wikittyDataCreationQ)); + con.commit(); + } catch (SQLException eee) { + con.rollback(); + } + closeConnection(con); + } catch (SQLException eee) { + if (log.isFatalEnabled()) { + log.fatal("Couldn't connect !"); + eee.printStackTrace(); + } + closeConnection(con); + throw new WikittyException(eee); + } + } + + @Override + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties, + boolean disableAutoVersionIncrement) throws WikittyException { + Connection con = null; + try { + con = getConnection(); + List<Command> result = new ArrayList<Command>(wikitties.size()); + for (Wikitty wikitty : wikitties) { + Statement statement = con.createStatement(); + ResultSet versionResultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), + COL_VERSION, adminTable, COL_ID, + "'" + wikitty.getId() + "'")); + StringBuffer batch = new StringBuffer(); + String version = null; + String newVersion = null; + String extensionList = ""; + boolean wikittyAlreadyExists = versionResultSet.first(); + + if (wikittyAlreadyExists) { + version = versionResultSet.getString(COL_VERSION); + + String wVersion = wikitty.getVersion(); + // test if wikitty version is more recent than database version + + if (WikittyUtil.versionEquals(version, wVersion)) { + // wikitty is not modified, do nothing + continue; + } else if (WikittyUtil.versionGreaterThan(version, wVersion)) { + throw new WikittyException(String.format( + "Your wikitty '%s' is obsolete", wikitty.getId())); + } + + // generate new version, but not change wikitty during prepare + newVersion = WikittyUtil.incrementMajorRevision(wVersion); + } else { + // generate new version, but not change wikitty during prepare + newVersion = WikittyUtil.incrementMajorRevision(version); + } + + batch.append(String.format(conf.getProperty(dataDeletionQ), wikitty.getId())); + + for (WikittyExtension ext : wikitty.getExtensions()) { + extensionList += "," + ext.getId(); + for (String fieldName : ext.getFieldNames()) { + FieldType type = ext.getFieldType(fieldName); + if (type.isCollection()) { + List<Object> list = wikitty.getFieldAsList(ext.getName(), + fieldName, Object.class); + if (list != null) { + switch (type.getType()) { + case BOOLEAN: + for (int i = 0; i < list.size(); i++) { + Boolean value = (Boolean) list.get(i); + batch.append(String.format(conf.getProperty(dataInsertQ), + COL_BOOLEAN_VALUE, wikitty.getId(), + ext.getName(), + fieldName + "[" + i + "/" + list.size() + "]", + value.toString())); + } + break; + case DATE: + for (int i = 0; i < list.size(); i++) { + Date value = (Date) list.get(i); + batch.append(String.format( + conf.getProperty(dataInsertQ), + COL_DATE_VALUE, wikitty.getId(), + ext.getName(), + fieldName + "[" + i + "/" + list.size() + "]", + "'" + new java.sql.Date(value.getTime()) + "'")); + } + break; + case NUMERIC: + for (int i = 0; i < list.size(); i++) { + BigDecimal value = (BigDecimal) list.get(i); + batch.append(String.format( + conf.getProperty(dataInsertQ), + COL_NUMBER_VALUE, wikitty.getId(), + ext.getName(), + fieldName + "[" + i + "/" + list.size() + "]", + value.toString())); + } + break; + case STRING: + for (int i = 0; i < list.size(); i++) { + String value = (String) list.get(i); + batch.append(String.format( + conf.getProperty(dataInsertQ), + COL_TEXT_VALUE, wikitty.getId(), + ext.getName(), + fieldName + "[" + i + "/" + list.size() + "]", + "'" + value.replace("'", "''") + "'")); + } + break; + case WIKITTY: + for (int i = 0; i < list.size(); i++) { + String value = (String) list.get(i); + batch.append(String.format( + conf.getProperty(dataInsertQ), + COL_TEXT_VALUE, wikitty.getId(), + ext.getName(), + fieldName + "[" + i + "/" + list.size() + "]", + "'" + value + "'")); + } + break; + default: + for (int i = 0; i < list.size(); i++) { + String value = (String) list.get(i); + batch.append(String.format( + conf.getProperty(dataInsertQ), + COL_TEXT_VALUE, wikitty.getId(), + ext.getName(), + fieldName + "[" + i + "/" + list.size() + "]", + "'" + value.replace("'", "''") + "'")); + } + break; + } + } else { + if (type.isNotNull()) { + throw new WikittyException(String.format( + "Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + } else { + switch (type.getType()) { + case BOOLEAN: + Boolean booleanValue = wikitty.getFieldAsBoolean(ext.getName(), fieldName); + if (booleanValue != null) { + batch.append(String.format( + conf.getProperty(dataInsertQ), COL_BOOLEAN_VALUE, + wikitty.getId(), ext.getName(), + fieldName, booleanValue.toString())); + } else { + System.out.println("#####DEBUG####" + type.toDefinition(fieldName)); + if (type.isNotNull()) { + throw new WikittyException(String.format("Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + break; + case DATE: + Date dateValue = wikitty.getFieldAsDate(ext.getName(), fieldName); + if (dateValue != null) { + batch.append(String.format( + conf.getProperty(dataInsertQ), COL_DATE_VALUE, + wikitty.getId(), ext.getName(), fieldName, + "'" + new java.sql.Date(dateValue.getTime()) + "'")); + } else { + System.out.println("#####DEBUG####" + type.toDefinition(fieldName)); + if (type.isNotNull()) { + throw new WikittyException(String.format("Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + break; + case NUMERIC: + Double numberValue = wikitty.getFieldAsDouble(ext.getName(), fieldName); + if (numberValue != null) { + batch.append(String.format( + conf.getProperty(dataInsertQ), COL_NUMBER_VALUE, + wikitty.getId(), ext.getName(), + fieldName, numberValue.toString())); + } else { + System.out.println("#####DEBUG####" + type.toDefinition(fieldName)); + if (type.isNotNull()) { + throw new WikittyException(String.format("Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + break; + case STRING: + String stringValue = wikitty.getFieldAsString(ext.getName(), fieldName); + if (stringValue != null) { + batch.append(String.format( + conf.getProperty(dataInsertQ), COL_TEXT_VALUE, + wikitty.getId(), ext.getName(), + fieldName, "'" + stringValue.replace("'", "''") + "'")); + } else { + System.out.println("#####DEBUG####" + type.toDefinition(fieldName)); + if (type.isNotNull()) { + throw new WikittyException(String.format("Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + break; + case WIKITTY: + Object objectValue = wikitty.getFieldAsObject(ext.getName(), fieldName); + if (objectValue != null) { + batch.append(String.format( + conf.getProperty(dataInsertQ), COL_TEXT_VALUE, + wikitty.getId(), ext.getName(), + fieldName, "'" + objectValue.toString().replace("'", "''") + "'")); + } else { + System.out.println("#####DEBUG####" + type.toDefinition(fieldName)); + if (type.isNotNull()) { + throw new WikittyException(String.format("Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + break; + default: + objectValue = wikitty.getFieldAsObject(ext.getName(), fieldName); + if (objectValue != null) { + batch.append(String.format( + conf.getProperty(dataInsertQ), COL_TEXT_VALUE, + wikitty.getId(), ext.getName(), + fieldName, "'" + objectValue.toString().replace("'", "''") + "'")); + } else { + System.out.println("#####DEBUG####" + type.toDefinition(fieldName)); + if (type.isNotNull()) { + throw new WikittyException(String.format("Field %s in extension %s can't be null", + fieldName, ext.getName())); + } + } + break; + } + } + } + } + if (extensionList.length() > 0) { + // delete first ',' + extensionList = extensionList.substring(1); + } + + if (wikittyAlreadyExists) { + // update wikitty object + String update = String.format(conf.getProperty(adminUpdateQ), + newVersion, extensionList, wikitty.getId()); + batch.insert(0, update); + + } else { + // insert wikitty object + String insert = String.format(conf.getProperty(adminInsertQ), + wikitty.getId(), newVersion, extensionList); + batch.insert(0, insert); + } + + Command command = new CommandJDBC(batch.toString(), wikitty, newVersion); + result.add(command); + } + return result; + } catch (SQLException eee) { + try { + con.rollback(); + } catch (SQLException eeee) { + eeee.printStackTrace(); + } + throw new WikittyException(eee); + } + + } + + @Override + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyStorageCommandList) { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + UpdateResponse result = new UpdateResponse(); + for (Command command : wikittyStorageCommandList) { + CommandJDBC commandJDBC = (CommandJDBC) command; + statement.execute(commandJDBC.queries); + + if (commandJDBC.toStore) { + Wikitty wikitty = commandJDBC.wikitty; + String newVersion = commandJDBC.version; + wikitty.setVersion(newVersion); + wikitty.clearDirty(); + + result.addVersionUpdate(wikitty.getId(), newVersion); + } else { + String id = commandJDBC.id; + Date date = commandJDBC.date; + result.addDeletionDateUpdate(id, date); + } + } + con.commit(); + closeConnection(con); + return result; + } catch (SQLException eee) { + closeConnection(con, true); + throw new WikittyException(eee); + } + + } + + @Override + public boolean exists(String id) { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + //select the data with the id "id" in the admin table + ResultSet resultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), COL_ID, + adminTable, COL_ID, "'" + id + "'")); + // return true if the query has a result + boolean result = resultSet.first(); + closeConnection(con); + return result; + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + } + + @Override + public boolean isDeleted(String id) { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + //select the data with the id "id" in the admin table + ResultSet resultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), + COL_DELETION_DATE, adminTable, COL_ID, "'" + id + "'")); + boolean result; + if (resultSet.first()) { + result = resultSet.getDate(COL_DELETION_DATE) != null; + closeConnection(con); + return result; + } else { + closeConnection(con); + throw new WikittyException(String.format( + "Wikitty with id '%s' doesn't exists", id)); + } + + } catch (SQLException eee) { + closeConnection(con); + throw new WikittyException(eee); + } + } + + @Override + public Wikitty restore( + String id, String... fqFieldName) throws WikittyException { + Connection con = null; + try { + con = getConnection(); + Statement statement = con.createStatement(); + //select the data with the id "id" in the admin table + ResultSet adminResultSet = statement.executeQuery( + String.format(conf.getProperty(notDeletedWhereSelectionQ), "*", + adminTable, COL_ID, "'" + id + "'")); + if (adminResultSet.first()) { + String version = adminResultSet.getString(COL_VERSION); + String extensionList = adminResultSet.getString(COL_EXTENSION); + //select the data with the id "id" in the data table + ResultSet dataResultSet = statement.executeQuery( + String.format(conf.getProperty(whereSelectionQ), "*", + dataTable, COL_ID, "'" + id + "'")); + Wikitty result = constructWikitty(id, version, extensionList, + dataResultSet, fqFieldName); + return result; + } else { + throw new WikittyException(String.format( + "Can't restore wikitty '%s'", id)); + } + } catch (Exception eee) { + throw new WikittyException(String.format( + "Can't restore wikitty '%s'", id), eee); + } + } + + @Override + public List<Wikitty> restore(Collection<String> ids, + String... fqFieldName) throws WikittyException { + List<Wikitty> result = new ArrayList<Wikitty>(ids.size()); + for (String id : ids) { + Wikitty w = restore(id, fqFieldName); + result.add(w); + } + return result; + } + + @Override + public List<Command> delete(List<String> ids) throws WikittyException { + try { + List<Command> result = new ArrayList<Command>(ids.size()); + Date now = new Date(); + + for (String id : ids) { + if (!exists(id)) { + throw new WikittyException(String.format( + "Wikitty with id '%s' doesn't exists", id)); + } else if (isDeleted(id)) { + throw new WikittyException(String.format( + "Wikitty with id '%s' is already deleted", id)); + } + // addVersionUpdate delete date field + StringBuffer batch = new StringBuffer(); + batch.append(String.format(conf.getProperty(adminDeletionQ), id)); + + result.add(new CommandJDBC(batch.toString(), id, now)); + + } + + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + + } + + /** + * Create Wikitty from h2 tables + * + * @param id the id of the wikitty to restore + * @param version the version of the wikitty to restore + * @param extensionList the list of the extensions of the wikitty to restore + * @param resultSet the ResultSet as the result of the selection of the in the data table + * @param fqFieldName minimum field to restore + * @return + */ + protected Wikitty constructWikitty(String id, String version, String extensionList, + ResultSet resultSet, String... fqFieldName) throws Exception { + Set<String> acceptedField = new HashSet<String>(Arrays.asList(fqFieldName)); + Wikitty result = new Wikitty(id); + result.setVersion(version); + if (extensionList != null && !"".equals(extensionList)) { + for (String ext : extensionList.split(",")) { + WikittyExtension extension = extensionStorage.restore(ext); + result.addExtension(extension); + } + } + + // load field + Map<String, Object[]> listFieldMap = new HashMap<String, Object[]>(); + resultSet.beforeFirst(); + while (resultSet.next()) { + // fqfieldName fully qualified fieldName (extention.fieldname) + String fqfieldName = resultSet.getString(COL_FIELDNAME); + if (isAcceptedField(acceptedField, fqfieldName)) { + FieldType type = result.getFieldType(fqfieldName); + Object value = null; + switch (type.getType()) { + case BOOLEAN: + value = resultSet.getBoolean(COL_BOOLEAN_VALUE); + break; + case DATE: + value = resultSet.getDate(COL_DATE_VALUE); + break; + case NUMERIC: + value = resultSet.getBigDecimal(COL_NUMBER_VALUE); + break; + case STRING: + value = resultSet.getString(COL_TEXT_VALUE); + break; + case WIKITTY: + value = resultSet.getString(COL_TEXT_VALUE); + break; + default: + value = resultSet.getString(COL_TEXT_VALUE); + break; + } + + if (type.isCollection()) { + // for list just stock array of element in map + Matcher match = listFieldPattern.matcher(fqfieldName); + if (match.find()) { + fqfieldName = match.group(1); + int index = Integer.parseInt(match.group(2)); + Object[] array = listFieldMap.get(fqfieldName); + if (array == null) { + int size = Integer.parseInt(match.group(3)); + array = new Object[size]; + listFieldMap.put(fqfieldName, array); + } + array[index] = value; + } else { + if (log.isErrorEnabled()) { + log.error(String.format( + "Can't read list field correctly '%s'", fqfieldName)); + } + } + } else { + result.setFqField(fqfieldName, value); + } + } + } + + // add fieldList in wikitty + for (String fieldName : listFieldMap.keySet()) { + Object[] array = listFieldMap.get(fieldName); + List list = new ArrayList(Arrays.asList(array)); + result.setFqField(fieldName, list); + } + + return result; + } + + /** + * Test if fqfieldName is in acceptedField + * + * @param acceptedField list of all accepted field + * @param fqfieldName fully qualified field name with potential [n/m] at end + * @return if fqfieldName without potential [n/m] is in acceptedField or if acceptedField is empty + */ + protected boolean isAcceptedField(Set<String> acceptedField, String fqfieldName) { + boolean result = acceptedField.isEmpty(); + if (!result) { + int crochet = fqfieldName.indexOf("["); + if (crochet != -1) { + fqfieldName = fqfieldName.substring(0, crochet); + } + + result = acceptedField.contains(fqfieldName); + } + + return result; + + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/AbstractJDBCTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/AbstractJDBCTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/AbstractJDBCTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,34 @@ +package org.sharengo.wikitty.jdbc; + +import java.util.Properties; + +import org.junit.After; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.sharengo.wikitty.WikittyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:META-INF/spring/wikitty-jdbc-test.xml") +public class AbstractJDBCTest { + + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + + } + + @Autowired + protected WikittyService ws; + + public void setWikittyService(WikittyService service) { + ws = service; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/BasicImportBench.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/BasicImportBench.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/BasicImportBench.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,41 @@ +package org.sharengo.wikitty.jdbc; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.test.util.GenTestData; +import org.sharengo.wikitty.test.util.ImportFeedback; + +public class BasicImportBench extends AbstractJDBCTest { + + public void testComplexSearch() throws Exception { + File reportFile = new File(System.getProperty("user.dir") + File.separator + "test3.log"); + final FileWriter writer = new FileWriter(reportFile); + + GenTestData.importGeneratedFile( + GenTestData.getDataFile("selected-data.txt"), + ws, + new ImportFeedback() { + + int index = 0; + + public void importPerformed(long nbImportedElements, long deltaTime) { + index++; + String str = String.format("%d\t%d\t%.2f\n", index, deltaTime, (deltaTime / (float) nbImportedElements)); + try { + writer.append(str); + } catch (IOException e) { + System.out.println("unable to write report line :" + str); + } + } + + public void parsed(Wikitty w) { + // do nothing + } + }); + + writer.close(); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/JDBCStorageTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/JDBCStorageTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/JDBCStorageTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,122 @@ +package org.sharengo.wikitty.jdbc; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.search.Element; +import org.sharengo.wikitty.search.Search; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class JDBCStorageTest extends AbstractJDBCTest { + + protected final static Log log = LogFactory.getLog(JDBCStorageTest.class); + private static String EXTNAME = "ExtName"; + + // not in StorageTest because InMemory don't support find + public void testExport() throws Exception { + final List<Wikitty> wikitties = createSampleWikitty(ws); + + Criteria criteria = Search.query().eq(Element.ELT_EXTENSION, EXTNAME).criteria(); + String result = ws.syncExportAllByCriteria(criteria); + log.debug("[XML] " + result); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse( new ByteArrayInputStream(result.getBytes()) ); + + Node rootNode = document.getChildNodes().item(0); + // check root node ... + assertEquals("wikengo", rootNode.getNodeName()); + + // check childs ... + acceptNodeList(rootNode.getChildNodes(), new NodeVisitor() { + public void visitNode( Node node, Map<String, String> attrs ) { + String nodeName = node.getNodeName(); + if ( "extension".equals(nodeName) ) { + assertEquals( "1", attrs.get("version") ); + assertEquals( "wikittyExt", attrs.get("name") ); + } else if ( "object".equals(nodeName) ) { + Wikitty wikitty = null; + for ( Wikitty w : wikitties ) { + if ( w.getId().equals(attrs.get("id")) ) { wikitty = w; break; } + } + assertNotNull( wikitty ); + assertEquals( "1.0", attrs.get("version") ); + assertEquals( "wikittyExt[1]", attrs.get("extensions") ); + wikitties.remove( wikitty ); + } else { + fail( "Node [" + node.getNodeName() + "] is neither an extension or an object" ); + } + + } + }); + + assertTrue( "some objects were not exported ...", wikitties.isEmpty() ); + } + + interface NodeVisitor { + public void visitNode( Node node, Map<String, String> attributes ); + } + + private void acceptNodeList( NodeList nodeList, NodeVisitor visitor ) { + int len = nodeList.getLength(); + Map<String, String> attrs = new HashMap<String, String>(); + for ( int i = 0; i < len; i ++) { + attrs.clear(); + Node node = nodeList.item(i); + if ( node.getNodeType() == Node.TEXT_NODE ) continue; + NamedNodeMap map = node.getAttributes(); + if ( map != null ) { + int attrLen = map.getLength(); + for( int j = 0; j < attrLen; j++ ) attrs.put(map.item(j).getNodeName(), map.item(j).getNodeValue()); + } + visitor.visitNode( node, attrs ); + } + } + + public void testImport() throws Exception { + InputStream in = JDBCStorageTest.class.getClassLoader().getResourceAsStream("basic-import.xml"); + byte[] buffer = new byte [ 8 * 1024 ]; + int read; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + while ((read = in.read(buffer)) > 0 ) { + bos.write(buffer, 0, read); + } + ws.syncImportFromXml( new String(bos.toByteArray()) ); + + String[] ids = new String[] { + "114ae525-932f-41cf-9f0a-dc6e2852c160", + "9339f649-b510-409d-89c7-779eb9e66e33", + "f5c2e46c-e646-422f-b474-8487aa034405" + }; + List<Wikitty> wikitties = ws.restore( Arrays.asList(ids) ); + assertEquals( 3, wikitties.size() ); + } + + private List<Wikitty> createSampleWikitty(WikittyService ws) { + // TODO Auto-generated method stub + return null; + } + + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/RemoteTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/RemoteTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/RemoteTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,5 @@ +package org.sharengo.wikitty.jdbc; + +public class RemoteTest { + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/SolrSearchTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/SolrSearchTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/SolrSearchTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,203 @@ +package org.sharengo.wikitty.jdbc; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Properties; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.PagedResult; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.search.Search; +import org.sharengo.wikitty.test.StorageTest; +import org.sharengo.wikitty.test.WikittyServiceTest; +import org.sharengo.wikitty.test.util.GenTestData; + +public class SolrSearchTest extends WikittyServiceTest { + + static private Log log = LogFactory.getLog(SolrSearchTest.class); + String extName = "Produit"; + + @Override + protected WikittyService createWikittyService() { + return new WikittyServiceJDBC(); + } + + + public void testBasicSearch() throws Exception { + createTestData(); + + Criteria criteria = Search.query() + .eq( extName + ".name_t", "chaise" ) + .criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + List<Wikitty> list = result.getAll(); + assertEquals( 1, list.size() ); + + Wikitty w = list.get(0); + assertEquals( "chaise", w.getFieldAsString(extName, "name") ); + assertEquals( 113311, w.getFieldAsInt(extName, "amount") ); + assertEquals( dateFormater.parse("26/09/2009"), w.getFieldAsDate(extName, "buildDate") ); + } + + public void testAdvancedSearch() throws Exception { + GenTestData.importGeneratedFile( GenTestData.getDataFile("selected-data.txt"), ws, null ); + + Criteria criteria = Search.query() + .eq( "Personne.nom_t", "AUMALE" ) + .criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + System.out.println( "solr query = " + result.getQueryString() ); + List<Wikitty> list = result.getAll(); + assertEquals( 3, list.size() ); + + for ( Wikitty w : list ) { + log.info("nom: " + w.getFieldAsString("Personne", "nom") + ", prenom: " + w.getFieldAsString("Personne", "prenom") ); + } + + criteria = Search.query() + .eq( "Personne.nom_t", "AUMALE" ) + .bw( "Employe.salaire_l", "50000", "100000" ) + .criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + + result = ws.findAllByCriteria(criteria); + System.out.println( "solr query = " + result.getQueryString() ); + list = result.getAll(); + assertEquals( 1, list.size() ); + + for ( Wikitty w : list ) { + log.info("nom: " + w.getFieldAsString("Personne", "nom") + ", prenom: " + w.getFieldAsString("Personne", "prenom") ); + } + + } + + private void createTestData() { + + LinkedHashMap<String, FieldType> fields = WikittyUtil.buildFieldMapExtension( + "String name", + "Numeric amount", + "Date buildDate" + ); + WikittyExtension ext = new WikittyExtension(extName, "1", null, fields); + + + ArrayList<Wikitty> result = new ArrayList<Wikitty>(); + ws.storeExtension( Arrays.asList( ext ) ); + String[] wValues = new String[] { + // wikitty[ 0 ] + "name = table," + + "amount = 003300," + + "buildDate = " + date("23/01/1982"), + + // wikitty[ 1 ] + "name = chaise," + + "amount = 113311," + + "buildDate = " + date("26/09/2009"), + + // wikitty[ 2 ] + "name = bureau," + + "amount = 223322," + + "buildDate = " + date("25/12/2029") + }; + for ( String wValue : wValues ) { + Wikitty w = StorageTest.createWikitty( wValue, extName, ext ); + result.add( w ); + } + ws.store(result); + } + + public void testAssociativeSearch() throws Exception { + WikittyExtension extProduct = new WikittyExtension("Product", "1", null, + WikittyUtil.buildFieldMapExtension( + "String name", + "Numeric price", + "Wikitty category") + ); + WikittyExtension extRayon = new WikittyExtension("Category", "1", null, + WikittyUtil.buildFieldMapExtension( + "String name") + ); + + Wikitty[] wikitties = createWikitties( extRayon, new String[] { + "name = Library", + "name = Stuff", + "name = Hardware", + "name = Staff", + "name = FooBar" + }); + + String hardwareCategoryId = wikitties[2].getId(); + String staffCategoryId = wikitties[3].getId(); + + createWikitties( extProduct, new String[] { + "name = Paint blue," + + "price = 20," + + "category = " + hardwareCategoryId, + + "name = Other Paint blue," + + "price = 20," + + "category = " + hardwareCategoryId, + + "name = Paint red," + + "price = 35," + + "category = " + hardwareCategoryId, + + "name = Paint Staff blue," + + "price = 20," + + "category = " + staffCategoryId, + + "name = Paint green," + + "price = 18," + + "category = " + hardwareCategoryId, + }); + + + Criteria criteria = Search.query() + .bw( "Product.price", "15", "25") + .sw( "Product.name", "Paint") + .associated( "Product.category" ) + .eq( "Category.name", "Hardware" ) + .criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + System.out.println( "solr query = " + result.getQueryString() ); + List<Wikitty> list = result.getAll(); + assertEquals( 2, list.size() ); + + for ( Wikitty w : list ) { + log.info("product-name: " + w.getFieldAsString("Product", "name") + ", product-price: " + w.getFieldAsString("Product", "price") ); + } + } + + private Wikitty[] createWikitties(WikittyExtension lonelyExtension, String[] wValues) { + ArrayList<Wikitty> result = new ArrayList<Wikitty>(); + for ( String wValue : wValues ) { + Wikitty w = StorageTest.createWikitty( wValue, lonelyExtension.getName(), lonelyExtension ); + result.add( w ); + } + ws.store(result); + return result.toArray( new Wikitty[]{} ); + } + + public static Test suite() { + TestSuite suite = new TestSuite(SolrSearchTest.class.getName()); + suite.addTest(TestSuite.createTest(SolrSearchTest.class, "testAssociativeSearch")); + return suite; + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/TreeTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/TreeTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/TreeTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,215 @@ +/* *##% + * Copyright (c) 2009 ruchaud. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty.jdbc; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.*; +import org.sharengo.wikitty.FieldType.TYPE; +import org.sharengo.wikitty.search.Search; +import org.sharengo.wikitty.solr.WikittySearchEngineSolr; +import org.sharengo.wikitty.test.StorageTest; + +/** + * + * @author ruchaud + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class TreeTest extends AbstractJDBCTest { + + static private Log log = LogFactory.getLog(TreeTest.class); + + static protected String EXTNAME = "ExtName"; + static protected WikittyExtension EXT_TEST; + + @Override + public void setUp() throws Exception { + super.setUp(); + createBasicWikitty(); + createTestData(); + } + + private void createTestData() { + // Create tree as following : + // root + // |_ node 1 + // | |_ node 11 + // | |_ node 12 + // | | |_ node 121 + // | |_ node 13 + // |_ node 2 + + createBranch("root/node1/node11"); + createBranch("root/node1/node12/node121"); + createBranch("root/node1/node13"); + createBranch("root/node2"); + + addNode("node11", "value 1"); + addNode("node11", "value 2"); + addNode("node11", "value 3"); + + addNode("node121", "value 4"); + addNode("node121", "value 5"); + + addNode("node2", "value 6"); + } + + protected void createBranch(String path) { + String parent = null; + String[] names = path.split("/"); + for (String name : names) { + + Wikitty found = findNode(name); + if(found == null) { + TreeNodeImpl node = new TreeNodeImpl(); + node.setName(name); + node.setParent(parent); + + found = node.getWikitty(); + log.debug("[Storing] " + name + " with id " + found.getId()); + ws.store(found); + assertNotNull(findNode(name)); + } + parent = found.getId(); + } + } + + protected void addNode(String nodeName, String value) { + Wikitty leaf = StorageTest.createWikitty("fieldName0=" + value, EXTNAME, EXT_TEST); + log.debug("[Storing] " + value + " with id " + leaf.getId()); + ws.store(leaf); + + Wikitty node = findNode(nodeName); + assertNotNull(node); + node.addToField(TreeNode.EXT_TREENODE, TreeNode.FIELD_CHILDREN, leaf.getId()); + + ws.store(node); + ws.store(leaf); + } + + protected Wikitty findNode(String nodeName) { + Criteria criteria = Search.query().eq(TreeNode.FQ_FIELD_NAME, nodeName).criteria(); + Wikitty wikitty = ws.findByCriteria(criteria); + return wikitty; + } + + protected int sumTopics(PagedResult<Wikitty> result, String facetName) { + List<FacetTopic> topics = result.getTopic(facetName); + int sum = 0; + if(topics != null) { + for (FacetTopic topic : topics) { + sum += topic.getCount(); + } + } + return sum; + } + +// public void testLoop() throws Exception { +// for (int count = 0; count < 10000; count++) { +// log.debug("[count] " + count); +// LabelImpl label = new LabelImpl(); +// label.addLabels("label" + count); +// Wikitty wikitty = label.getWikitty(); +// ws.store(wikitty); +// Criteria criteria = Search.query().eq(Label.FQ_FIELD_LABELS, "label" + count).criteria(); +// ws.findByCriteria(criteria); +// } +// } + + public void testRestoreTree() throws Exception { + Wikitty root = findNode("root"); + String rootId = root.getId(); + + Tree tree = ws.restoreTree(rootId); + assertNotNull(tree); + } + + public void testHiearchicalFacet() throws Exception { + Wikitty root = findNode("root"); + String rootId = root.getId(); + + Criteria criteria = Search.query().eq(WikittySearchEngineSolr.TREENODE_ROOT, rootId).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS) + .addFacetField(rootId); + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + int sum = sumTopics(result, rootId); + logFacets(result); + assertEquals(6, sum); + + Wikitty node1 = findNode("node1"); + String node1Id = node1.getId(); + + criteria = Search.query().eq(rootId, node1Id).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS) + .addFacetField(node1Id); + result = ws.findAllByCriteria(criteria); + sum = sumTopics(result, node1Id); + logFacets(result); + assertEquals(5, sum); + + Wikitty node11 = findNode("node11"); + String node11Id = node11.getId(); + + criteria = Search.query().eq(node1Id, node11Id).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS) + .addFacetField(node11Id); + result = ws.findAllByCriteria(criteria); + sum = sumTopics(result, node11Id); + logFacets(result); + assertEquals(0, sum); + } + + protected void logFacets(PagedResult<Wikitty> result) { + log.debug("Result : " + result.getQueryString() + " (" + result.getNumFound() + ")"); + Collection<String> facetNames = result.getFacetNames(); + for (String facetName : facetNames) { + log.debug("Facet " + facetName); + List<FacetTopic> topics = result.getTopic(facetName); + for (FacetTopic topic : topics) { + log.debug("Topic " + topic.getTopicName() + "(" + topic.getCount() + ")"); + } + } + } + + public void testRestoreChildren() throws Exception { + Wikitty node1 = findNode("node1"); + String node1Id = node1.getId(); + + Map<TreeNode, Integer> children = ws.restoreChildren(node1Id); + assertEquals(3, children.size()); + } + + private Wikitty createBasicWikitty() { + WikittyExtension ext = ExtensionFactory.create(EXTNAME, "1") + .addField("name", TYPE.STRING) + .extension(); + Wikitty w = new Wikitty(); + w.setField(EXTNAME, "name", "foobar"); + return w; + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/WikittySearchEngineTest.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/WikittySearchEngineTest.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/jdbc/WikittySearchEngineTest.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,292 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty.jdbc; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import junit.framework.TestCase; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.FacetTopic; +import org.sharengo.wikitty.PagedResult; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.search.Search; +import org.sharengo.wikitty.test.util.GenTestData; +import org.sharengo.wikitty.test.util.ImportFeedback; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittySearchEngineTest extends TestCase { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittySearchEngineTest.class); + + /** 10 search by field */ + static final int MAX = 10; + + static String[] allFieldNames = new String[]{ + "Personne.civilite", + "Personne.nom", + "Personne.prenom", + "Personne.date_naissance", + "Personne.poids", + "Employe.matricule", + "Employe.arrivee", + "Employe.salaire" + }; + + /** + * used to count some element during data loading, this information + * is used to assert statement + */ + static public class AssertReference implements ImportFeedback { + + /** total number imported elements */ + public int count = 0; + /** key: fqfieldname value: map(fieldvalue, count this value) */ + public Map<String, Map<Object, Integer>> fieldValueCounters = + new HashMap<String, Map<Object, Integer>>(); + + public void importPerformed(long nbImportedElements, long deltaTime) { + // do nothing + } + + public void parsed(Wikitty w) { + count++; + + for (String fqf : allFieldNames) { + Map<Object, Integer> fvc = fieldValueCounters.get(fqf); + if (fvc == null) { + fvc = new HashMap<Object, Integer>(); + fieldValueCounters.put(fqf, fvc); + } + Object key = w.getFqField(fqf); + Integer n = fvc.get(key); + if (n == null) { + n = 1; + } else { + n = n + 1; + } + fvc.put(key, n); + } + } + + } + + WikittyService ws; + AssertReference assertReference; + + // TODO poussin 20090901 this method is call for each test method, this method can be call only once for all test methods + @Override + public void setUp() throws Exception { + // import data and prepare expected result + ws = new WikittyServiceJDBC(); + ((WikittyServiceJDBC)ws).getSearchEngine().clear(); + assertReference = new AssertReference(); + GenTestData.importGeneratedFile( + GenTestData.getDataFile("selected-data.txt"), ws, assertReference); + + } + + /** + * Do MAX search for each field in object and compare result size with + * number found during import + * + * @throws Exception + */ + public void testFindByExample() throws Exception { + for (String fqf : allFieldNames) { + int cpt = 0; // cpt to stop loop after amount of test + Wikitty w = new Wikitty(); + w.addExtension(GenTestData.ext_personne); + w.addExtension(GenTestData.ext_employe); + + Map<Object, Integer> fvc = assertReference.fieldValueCounters.get(fqf); + for (Object value : fvc.keySet()) { + System.out.println("search on: " + fqf + " with value: " + value); + if(++cpt >= MAX) { + break; + } + int nb = fvc.get(value); + w.setFqField(fqf, value); + Criteria criteria = Search.query(w).criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + System.out.println("Count: " + result.size() + " Query: " + result.getQueryString()); + assertEquals(nb, result.size()); + } + } + } + + /** + * Do MAX search for each field in object and compare result size with + * number found during import + * + * @throws Exception + */ + public void testFindByCriteria() throws Exception { + for (String fqf : allFieldNames) { + int cpt = 0; // cpt to stop loop after amount of test + + int sum = 0; // sum number of finding object for this fqf + List values = new LinkedList(); + + Map<Object, Integer> fvc = assertReference.fieldValueCounters.get(fqf); + for (Object value : fvc.keySet()) { + if(++cpt >= MAX) { + break; + } + int nb = fvc.get(value); + + // stock number and value for last test + sum += nb; + values.add(value); + + Criteria criteria = Search.query() + .eq(fqf, WikittyUtil.toString(value)) + .criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + + assertEquals(nb, result.size()); + } + + Search query = Search.query().or(); + for (Object value : values) { + query.eq(fqf, WikittyUtil.toString(value)); + } + Criteria criteria = query.criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS); + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + System.out.println("query: " + result.getQueryString()); + assertEquals(sum, result.size()); + } + } + + /** + * Do search for 'Personne.nom==*' for limited result number, total number + * available in solr must be equals to number found during import + * + * @throws Exception + */ + public void testFindByCriteriaNumFound() throws Exception { + String fqf = "Personne.nom"; + Criteria criteria = Search.query().neq(fqf, "aaaaa").criteria() + .setFirstIndex(0).setEndIndex(2); + + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + + assertEquals(assertReference.count, result.getNumFound()); + } + + /** + * Do search on Personne.nom and ask facet for Personne.nom, all Topic + * must be equals (name and count) to name and number found during import + * + * @throws Exception + */ + public void testFindByCriteriaFieldFacet() throws Exception { + String fqf = "Personne.nom"; + Map<Object, Integer> fvc = assertReference.fieldValueCounters.get(fqf); + Criteria criteria = Search.query().neq(fqf, "aaaaa").criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS) + .addFacetField(fqf); + + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + + assertEquals(new ArrayList(Arrays.asList(fqf)), + new ArrayList(result.getFacetNames())); + List<FacetTopic> topics = result.getTopic(fqf); + + for (FacetTopic t : topics) { + String name = t.getTopicName(); + int num = t.getCount(); + + System.out.println("name: " + name + " keys: " + fvc.keySet()); + assertNotNull(fvc.get(name)); + int realNum = fvc.get(name); + assertEquals(realNum, num); + } + } + + /** + * Do search on Personne.nom and ask facet for Personne.civilite 2 + * named facet criteria: + * - homme (civilite==Mr) + * - femme (civilite==Me OR civilite==Mlle) + * + * @throws Exception + */ + public void testFindByCriteriaCriteriaFacet() throws Exception { + String fqf = "Personne.nom"; + String facetName = "Personne.civilite"; + + Criteria homme = Search.query().eq(facetName, "Mr").criteria("homme"); + Criteria femme = Search.query() + .eq(facetName, "Me").or().eq(facetName, "Mlle") + .criteria("femme"); + + Criteria criteria = Search.query().neq(fqf, "aaaaa").criteria() + .setFirstIndex(0).setEndIndex(WikittyService.ALL_ELEMENTS) + .addFacetCriteria(homme).addFacetCriteria(femme); + + PagedResult<Wikitty> result = ws.findAllByCriteria(criteria); + + assertEquals(2, result.getFacetNames().size()); + + System.out.println("facet names: " + result.getFacetNames()); + + assertNotNull(assertReference.fieldValueCounters.get(facetName).get("Mr")); + assertNotNull(assertReference.fieldValueCounters.get(facetName).get("Me")); + assertNotNull(assertReference.fieldValueCounters.get(facetName).get("Mlle")); + + int numMr = assertReference.fieldValueCounters.get(facetName).get("Mr"); + int numMe = assertReference.fieldValueCounters.get(facetName).get("Me"); + int numMlle = assertReference.fieldValueCounters.get(facetName).get("Mlle"); + + log.info("numMr: " + numMr); + log.info("numMe: " + numMe); + log.info("numMlle: " + numMlle); + + List<FacetTopic> hommeTopics = result.getTopic("homme"); + List<FacetTopic> femmeTopics = result.getTopic("femme"); + + assertEquals(1, hommeTopics.size()); + assertEquals(1, femmeTopics.size()); + + FacetTopic hommeTopic = hommeTopics.get(0); + FacetTopic femmeTopic = femmeTopics.get(0); + + assertEquals(numMr, hommeTopic.getCount()); + assertEquals(numMe + numMlle, femmeTopic.getCount()); + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVDataVisitor.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVDataVisitor.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVDataVisitor.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,9 @@ +package org.sharengo.wikitty.test.util; + +public interface CSVDataVisitor { + + public void begin(); + public void visitData( String[] headers, String[] data ); + public void end(); + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVUtils.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVUtils.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVUtils.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,24 @@ +package org.sharengo.wikitty.test.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class CSVUtils { + + public static void acceptFile( File file, CSVDataVisitor visitor ) throws IOException { + BufferedReader reader = new BufferedReader( new FileReader(file) ); + visitor.begin(); + String[] headers = reader.readLine().trim().split(";"); + String line; + String data[]; + while( (line = reader.readLine()) != null ) { + data = line.split(";"); + visitor.visitData(headers, data); + } + visitor.end(); + reader.close(); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVWikittyBulkImport.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVWikittyBulkImport.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/CSVWikittyBulkImport.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,86 @@ +package org.sharengo.wikitty.test.util; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyService; + + +public class CSVWikittyBulkImport implements CSVDataVisitor { + + WikittyExtension[] extensions = new WikittyExtension[]{}; + long batchSize = 1000; + long num = 0; + + List<Wikitty> wikitties; + WikittyService ws; + + long to_time, from_time; + + ImportFeedback feedback; + + public CSVWikittyBulkImport(WikittyService ws, WikittyExtension[] extensions) { + this.ws = ws; + this.wikitties = new ArrayList<Wikitty>(); + this.extensions = extensions; + } + + public void setFeedback(ImportFeedback feedback) { + this.feedback = feedback; + } + + public void setBatchSize(long batchSize) { + this.batchSize = batchSize; + } + + public void begin() { + from_time = System.currentTimeMillis(); + } + + public void visitData(String[] headers, String[] data) { + Wikitty w = new Wikitty(); + + w.addExtension( Arrays.asList(extensions) ); + + for ( int y = 0; y < headers.length; y++ ) { + w.setFqField( headers[y], data[y] ); + } + wikitties.add(w); num++; + if ( feedback != null ) { + feedback.parsed(w); + } + if ( num >= 1000 ) { + doImport(); + } + } + + private void doImport() { + ws.store(wikitties); + wikitties.clear(); + if ( feedback != null ) { + to_time = System.currentTimeMillis(); + feedback.importPerformed(num, to_time - from_time); + num = 0; + from_time = to_time; + } + } + + public void end() { + if ( !wikitties.isEmpty() ) { + doImport(); + } + } + + public static void importFile( File file, WikittyExtension[] extensions, + WikittyService ws, ImportFeedback feedback ) throws IOException { + CSVWikittyBulkImport visitor = new CSVWikittyBulkImport(ws, extensions); + visitor.setFeedback(feedback); + CSVUtils.acceptFile(file, visitor); + } + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/GenTestData.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/GenTestData.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/GenTestData.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,166 @@ +package org.sharengo.wikitty.test.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyService; +import org.sharengo.wikitty.WikittyUtil; +import org.sharengo.wikitty.jdbc.WikittyServiceJDBC; +import org.sharengo.wikitty.search.Element; +import org.sharengo.wikitty.search.Search; + +public class GenTestData { + + public String[] + civilites = new String[] { "Mr", "Me", "Mlle" }, + noms, + prenoms; + + PrintWriter writer; + + public static WikittyExtension + ext_personne = new WikittyExtension( + "Personne", "1", null, + WikittyUtil.buildFieldMapExtension( + "String civilite", + "String nom", + "String prenom", + "Date date_naissance", + "Numeric poids" + ) + ), + ext_employe = new WikittyExtension( + "Employe", "1", null, + WikittyUtil.buildFieldMapExtension( + "String matricule", + "Date arrivee", + "Numeric salaire" + ) + ); + + public GenTestData(File file) throws IOException{ + writer = new PrintWriter( new FileWriter( file ) ); + + noms = initData( "noms" ); + prenoms = initData( "prenoms" ); + + writeHeader( writer ); + for( int i = 0; i < 100000; i++ ) { + if ( i % 1000 == 0 ) System.out.print("."); + writeRandomData( i ); + } + writer.flush(); + writer.close(); + System.out.println(); + } + + private String[] initData( String resourcePath ) throws IOException { + InputStream in = GenTestData.class.getClassLoader().getResourceAsStream(resourcePath); + BufferedReader r = new BufferedReader( new InputStreamReader(in) ); + String line; + List<String> result = new ArrayList<String>( 100 ); + while( (line = r.readLine()) != null ) { + line = line.trim(); + if ( line.isEmpty() ) continue; + result.add( line ); + } + return result.toArray( new String[]{} ); + } + + private void writeRandomData(int i) { + String[] data = new String[] { + random(civilites), // "Personne.civilite", + random(noms), // "Personne.nom", + random(prenoms), // "Personne.prenom", + randomDate(1950, 1990), // "Personne.date_naissance", + randomInt(50, 110), // "Personne.poids", + randomInt(10000, 99000), //"Employe.matricule", + randomDate(1990, 2009), // "Employe.arrivee", + randomInt(20000, 200000), // "Employe.salaire" + }; + writeLine( data ); + } + + private void writeLine(String[] data) { + boolean first = true; + for( String str : data ) { + if ( !first ) writer.append(";"); else first = false; + writer.append( str ); + } + writer.println(); + } + + private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); + private String randomDate(int fromYear, int toYear) { + try { + return WikittyUtil.solrDateFormat.format( + dateFormat.parse( + (r.nextInt(28) + 1) + + "/" + (r.nextInt(12) + 1) + + "/" + randomInt(fromYear, toYear) + ) + ); + } catch (ParseException e) { + return null; + } + } + + private String randomInt( int from, int to ) { + int interval = to - from; + return "" + (r.nextInt(interval) + from); + } + + private Random r = new Random(); + private String random(String[] array) { + return array[ r.nextInt(array.length) ]; + } + + private void writeHeader(PrintWriter writer) { + String[] headers = new String[] { + "Personne.civilite", + "Personne.nom", + "Personne.prenom", + "Personne.date_naissance", + "Personne.poids", + "Employe.matricule", + "Employe.arrivee", + "Employe.salaire" + }; + writeLine(headers); + } + + public static void importGeneratedFile( File file, WikittyService ws, ImportFeedback importFeedback ) throws IOException { + CSVWikittyBulkImport.importFile( + file, + new WikittyExtension[]{GenTestData.ext_personne, GenTestData.ext_employe}, + ws, + importFeedback + ); + } + + public static File getDataFile(String localName) { + return new File( System.getProperty("user.dir") + File.separator + "src/test/resources/" + localName ); + } + + public static void main(String[] args) throws Exception { +// File file = getDataFile( "random-data.txt" ); +// new GenTestData( file ); + + WikittyService ws = new WikittyServiceJDBC(); + //ws.findAllByCriteria(Search.query().eq("name","*test*").criteria()); + ws.findAllByCriteria(Search.query().keyword("*test*").criteria()); + + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/ImportFeedback.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/ImportFeedback.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/java/org/sharengo/wikitty/test/util/ImportFeedback.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,12 @@ +package org.sharengo.wikitty.test.util; + +import org.sharengo.wikitty.Wikitty; + +public interface ImportFeedback { + + public void importPerformed(long nbImportedElements, long deltaTime); + + /** called for each Wikitty create */ + public void parsed(Wikitty w); + +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/basic-import.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/basic-import.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/basic-import.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,22 @@ +<wikengo> + <extension name='wikittyExt' version='1'> + <field>STRING fieldName0[0-0]</field> + <field>NUMERIC fieldName1[0-0]</field> + <field>DATE fieldName2[0-0]</field> + </extension> + <object id='114ae525-932f-41cf-9f0a-dc6e2852c160' version='1.0' extensions='wikittyExt[1]'> + <wikittyExt.fieldName0>table</wikittyExt.fieldName0> + <wikittyExt.fieldName1>3300</wikittyExt.fieldName1> + <wikittyExt.fieldName2>1982-01-23T00:00:00.000Z</wikittyExt.fieldName2> + </object> + <object id='9339f649-b510-409d-89c7-779eb9e66e33' version='1.0' extensions='wikittyExt[1]'> + <wikittyExt.fieldName0>bureau</wikittyExt.fieldName0> + <wikittyExt.fieldName1>223322</wikittyExt.fieldName1> + <wikittyExt.fieldName2>1929-12-25T00:00:00.000Z</wikittyExt.fieldName2> + </object> + <object id='f5c2e46c-e646-422f-b474-8487aa034405' version='1.0' extensions='wikittyExt[1]'> + <wikittyExt.fieldName0>chaise</wikittyExt.fieldName0> + <wikittyExt.fieldName1>113311</wikittyExt.fieldName1> + <wikittyExt.fieldName2>2009-09-26T00:00:00.000Z</wikittyExt.fieldName2> + </object> +</wikengo> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/jdbc.properties =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/jdbc.properties (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/jdbc.properties 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,71 @@ +#Connection parameters +jdbc.con.driver=org.h2.Driver +jdbc.con.host=jdbc:h2:~/wikitty +jdbc.con.userName=sa +jdbc.con.password= + +#table extension_admin creation query +jdbc.queries.creation.extension.admin=CREATE TABLE IF NOT EXISTS extension_admin (\ +id text NOT NULL,\ +name text NOT NULL,\ +version varchar(8) NOT NULL);\ +ALTER TABLE extension_admin ADD PRIMARY KEY (id); + +#table extension_data creation query +jdbc.queries.creation.extension.data=CREATE TABLE IF NOT EXISTS extension_data (\ +fieldName text NOT NULL,\ +fieldType text NOT NULL,\ +id text NOT NULL);\ +ALTER TABLE extension_data ADD PRIMARY KEY (id,fieldName);\ +ALTER TABLE extension_data ADD FOREIGN KEY (id) REFERENCES extension_admin (id); + +#table wikitty_admin creation query +jdbc.queries.creation.wikitty.admin=CREATE TABLE IF NOT EXISTS wikitty_admin (\ +id varchar(64) NOT NULL,\ +version varchar(8) NOT NULL,\ +extension_list text NOT NULL,\ +deletionDate dateTime DEFAULT NULL);\ +ALTER TABLE wikitty_admin ADD PRIMARY KEY (id); + +#table wikitty_data creation query +jdbc.queries.creation.wikitty.data=CREATE TABLE IF NOT EXISTS wikitty_data (\ +fieldName text NOT NULL,\ +numberValue numeric,\ +dateValue datetime,\ +textValue text,\ +booleanValue boolean,\ +id varchar(64) NOT NULL);\ +ALTER TABLE wikitty_data ADD PRIMARY KEY (id,fieldName);\ +ALTER TABLE wikitty_data ADD FOREIGN KEY (id) REFERENCES wikitty_admin (id); + +#basic selection query without where clause +jdbc.queries.select=SELECT %s FROM %s; +#basic selection query with where clause +jdbc.queries.select.where=SELECT %s FROM %s WHERE %s = %s; +#not deleted data selection query with where clause +jdbc.queries.select.where.notdeleted=SELECT %s FROM %s WHERE %s = %s AND deletionDate IS NULL; + +#tables emptying query +jdbc.queries.delete.all=DELETE FROM extension_data; DELETE FROM extension_admin;\ +DELETE FROM wikitty_data; DELETE FROM wikitty_admin; +#wikitty deletion in the admin table query +jdbc.queries.delete.wikitty.admin=UPDATE wikitty_admin SET deletionDate = NOW()\ +WHERE id = '%s'; +#wikitty deletion in the data table query +jdbc.queries.delete.wikitty.data=DELETE FROM wikitty_data WHERE id = '%s'; + +#wikitty insertion in the admin table query +jdbc.queries.insert.wikitty.admin=INSERT INTO wikitty_admin\ +(id, version, extension_list) VALUES ('%s', '%s', '%s'); +#wikitty update in the admin table query +jdbc.queries.update.wikitty.admin=UPDATE wikitty_admin\ +SET version = '%s', extension_list = '%s' WHERE id = '%s'; +#wikitty insertion in the data table query +jdbc.queries.insert.wikitty.data=INSERT INTO wikitty_data\ +(id, fieldName, %s) VALUES ('%s', '%s.%s', %s); +#extension insertion in the admin table query +jdbc.queries.insert.extension.admin=INSERT INTO extension_admin\ +(id, name, version) VALUES ('%s', '%s', '%s'); +#extension insertion in the data table query +jdbc.queries.insert.extension.data=INSERT INTO extension_data\ +(id, fieldName, fieldType) VALUES ('%s', '%s', '%s'); \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/log4j.properties =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/log4j.properties (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/log4j.properties 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,9 @@ +# Appender and Layout +log4j.appender.logConsole=org.apache.log4j.ConsoleAppender +log4j.appender.logConsole.layout=org.apache.log4j.PatternLayout +log4j.appender.logConsole.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n + +# Configuration by components +log4j.rootLogger=ERROR, logConsole +log4j.logger.org.sharengo.wikitty=DEBUG +log4j.logger.org.apache.solr=DEBUG Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/noms =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/noms (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/noms 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,926 @@ + ABBEVILLE + ADDENIN + AILLY + AIMÃE + ALENÃON + ALEXANDRE + ALLAIN + ALLUISON + ALSACE + AMIENS + AMORY + ANJOU + ANNEQUIN + AQUITAINE + ARDRES + ARGENTON + ARGIES + ARLES + ARNAUD + ARRAULT + ASPREMONT + ASSIGNIES + ASSONLEVILLE + AUBIGNY + AUBOUARE + AUCHOEL + AUGENDRE + AUGER + AUGONNET + AUMALE + AUSTINE + AUVERGNE + AUXY + AVANTIGNY + AVERHOUST + AVESNES + AZINCOURT + BACHELIER + BACQUEHEM + BAES + BAILLEUL + BAILLOT + BAILLY + BALLOT + BAR + BARAT de LA HAYE + BARBANÃON + BARBAT + BARBIER + BARCELONE + BARDEAU + BARRAUT + BATHEREAU + BAUDART + BAUDEMENT + BAUGà + BAUGENCY + BAULIER + BAUX + BEAUFREMEZ + BEAUFREMONT + BEAUJEAN + BEAUJEU + BEAUMONT + BEAUPARISIS + BEAUVAIS + BECQUET + BELLAY + BELLEVAL + BELLONE + BENARD + BÃRENGER + BERGHES + BERLAND + BERNARD + BERNÃTRE + BERNICOURT + BERRY + BERTIER + BERTIN + BERTRAND + BESANÃON + BESQUE + BÃTHENCOURT + BÃTHUNE + BEUGNET + BEUGNON + BEURIOT + BEUVRY + BEZOU + BIENASSIS + BIENCOURT + BIENQUE + BILLEMONT + BIRAGUE + BLANCHARD + BLANCHER + BLANDY + BLOIS + BLONDEL + BOICHOT + BOILEAU + BOIS + BOIS de HOVES + BOISEAUX + BOISSARD + BOISSEAU + BOISVILLIERS + BOMEZ + BOMMEZ + BONARD + BONNAFAU + BORDELET + BORDET + BOS + BOSEVENT + BOUBERS + BOUCHER + BOUDET + BOUDOU + BOULAT + BOULE + BOULLENCOURT + BOURBON + BOURBOURG + BOURGEOIS + BOURGOGNE + BOURGOIN + BOURNEL + BOURNONVILLE + BOURRIS + BOURSIN + BOUSSARD + BOUTERY + BOUVILLE + BOYAVAL + BRABANT + BRAQUE + BRENETOT + BRESOT + BRETAGNE + BRETEUIL + BRIENNE + BRIGNAC + BRILLE + BRIQUOIS + BRISSIER + BRISSON + BRISTEL + BROCELANCE + BROSSARD + BROUTIN + BRULLOZ + BRUMARE + BRUNET + BUNEL +CADET + CADY + CAILLAT + CALLEMENT + CALONNE + CAMBRIN + CAMBUZAT + CANCER + CANDAVENE + CANIVET + CANTRELLE + CARINTHIE + CARIOT + CARPENTIER + CARRE + CARRETTE + CARUE + CASSEL + CASSEMICHE + CASTELLOISE + CASTILLE + CATHELAIN + CATHEU + CAUDRELIER + CAUMESNIL + CERCUEIL + CERF + CHALON + CHAMPAGNE + CHAMPIGNY + CHANE + CHANTEREAU + CHANTOCà + CHARDON + CHARENTON + CHARLOT + CHARRIE + CHARTIER + CHASLOUP + CHASSENNEAU + CHASTEL + CHASTILLON + CHÃTEAULANDON + CHÃTEAUNEUF + CHÃTELLERAULT + CHATENET + CHAUMERON + CHAUMONT + CHENERY + CHENU + CHERBUY + CHERISY + CHERON + CHEVALIER + CHEVILLON + CHEVILLOT + CHEVRETTE + CHOPPIN + CHOUQUET + CHOURSES +CLAIRET + CLÃMANDORT + CLÃMENT + CLERMONT + CLÃRY + COLACHOT + COLBEAU + COLLAS + COLLET + COLOMBAT + COMMANVILLE + COMNÃNE + CONJEAUD + CONVERSAT + COQUIBUS + COQUILLE + CORDES + CORICHON + CORNU + COSSON + COTARD + COTTENSIN + COTTREL + COUCY + COUDRET + COUPPIN + COURCELLE + COURGENOUL + COURONNEL + COURROUX + COURTENAY + COUTHRIER + CRAON + CRÃCY + CREPIN + CRÃQUY + CRESPIN + CRESSON + CRESTE + CREUZET + CROCHOT + CUINGEN + CUNCHY + CUSANI +DABRIAS + DAIRE + DALLEMAGNE + DAMIENS + DAMOIS + DAMOISEAU + DAMPIERRE + DAMPMARTIN + DARLEY + DARLOT + DAUTHON + DAUVISSAT + DAVID de CONFLANS + DEBERNARD + DEBUIRE + DEFRANCE + DEGUION + DEGUY + DEHAY + DELACOUR + DELANOY + DELAPIERRE + DELAPORTE + DELAROQUE + DELATTRE + DELAVEAU + DELCROIX + DELHOMME + DELORME + DELVIGNE + DEMEAUX + DEMERY + DEMORY + DENIS + DEPAIR + DERANCOURT + DERCKEL + DERIENCOURT + DEROME + DERY + DERUY + DERVILLERS + DESBOEUFS + DESCAMPS + DESCHAINTRE + DESCLUZEAUX + DESCOURS + DESGRANGES + DESMOLINS + DESPONCHEAUX + DEVEAU + DEVILLE + DEY + DIZIER + DONJON + DONZY + DORE + DOUTREMEPUICH + DREUX + DREVILLE + DUBUISSON + DUBUSC + DUCLOS + DUCROT + DUDOUT + DUGON + DUISYE + DUPAS + DUPONT + DUPUICH + DURAND + DURVILLE + DUVAL + DUVEAU +ESCABILLON + ESCLAIBES + ESNE + EU + EVE + EVRAT + ÃVREUX +FAUCONNIER + FAY + FEVRE + FIENNES + FILLEU + FIQUET + FLANDRES + FLEURIGNY + FLOS + FONTAINE + FONTY + FORCALQUIER + FOREST + FOUCHER + FOUET + FOUILLAUX + FOUQUAY + FOURNEAU + FOURNIER + FOURREY + FOURSY + FRAMECOURT + FRANCE + FRANQUIN + FREAUD + FRICAMPS + FROMON + FUZIER +GALBART + GALVEUX + GAMARD + GANNEAU + GAQUEREL + GARDIN + GARES + GARLANDE + GARNY + GAUCHER + GAUDRY + GAUGUIER + GAUTHERIN + GAYOT + GEOFFROY + GERMAIN + GERMIGNY + GHERQUIER + GHISTELLES + GILARDIN + GIRAUDON + GISORS + GOFFERT + GOMMEGNIES + GOMMETS + GOMOT + GOUGEARD + GOURLOT + GOUY + GRAÃAY + GRANDPRà + GRANDSIRE + GRANGE + GRARD + GRAVEREAU + GREBERT + GRÃGOIRE + GRENET + GRIBOVAL + GRIGNARD + GRILLOT + GRIMIER + GRIMOIN + GROSPRà + GUELDRES + GUENAND + GUENECH + GUENIER + GUENIN + GUERCHY + GUERREAU + GUESSET + GUICHARD + GUIDAMOUR + GUIDON + GUIDOU + GUILBERT + GUILLAUME + GUILLà + GUILLEMIN + GUILLEMOT + GUILLOT + GUINBERT + GUINES + GUINIÃRE + GUINOT + GUISARME + GUISE +HABARCQ + HABERT + HACK + HALLENGUES + HALLWIN + HAM + HAMELIN + HANGEST + HARCHIES + HARCOURT + HARDENTHUN + HARRY + HAVESKERQUE + HAYNAUT + HÃBUTERNE + HEILLY + HENAU + HENRION + HENRY + HÃRAT + HERBET + HERGOT + HERMER + HERVIEUX + HESQUES + HINGETTES + HOLLANDE + HOULIER + HUBERT + HUGOT + HUGUET + HUOT + HUQUEDIEU + HURE + HURET +JACOB + JACQUET + JAMET + JANNETON + JANNIOT + JARCY + JASQUIER + JAUSSE + JAY + JEANNEAU + JEANNIN + JOIGNY + JOSSE + JOUSSOT + JULLY + JUMELLE +La BARRE + La BROSSE + La CAILLE + La CHAPELLE + LACHAUME + LA CROIX + LA DEULLE + LADMIRAL + LA FORGE + LAINE + LALAING + LAMARRE + LAMBERSAT + LAMBLIN + LAMPOGNANI + LAMY + LANCHÃRES + LANGHEMEERSCH + LANIER + LANNOY + LANTHIER + LA RIVIÃRE + LA ROCHE + LA ROCHE-DRONION + LA ROCHEGUYON + La ROSIÃRE + LA ROUà + LA SALLE + La TRÃMOILLE + LATROYE + LAUNAY + LAURENT + LAURIN + LA VACQUERIE + LAVAL + LA VERNADE + LE CARON + LE CAUCHIE + LECERF + LE CHANGEUR + LECLAIR + LE CLEF + LECLERC + LECLERCQ + LE COEUR + LECOMTE + LE COURTOIS + LEDOUX + LE DROUAIS + LE FEBURE + LEFEBVRE + LE FEUTRE + LE FORT + LEGAGE + LEGAR + LEGAY + LEGRAND + LEGUEUX + Le JART + LEJEUNE + LEJONG + LELEU + LE MACHON + LEMAIRE + LE MERLE + LEMORT + LENFANT + LENFERNAT + LENS + LÃON + LEPARGNEUX + LEROUX + LEROY + LE RUELLE + LESAGE + LE SAULX + LESAUVAGE + LESENNE + LESLEIN + LESSOPIER + LESTRIOT + LE TELLIER + LETERME + LETOURNEAU + Le VASSEUR + LEVESIER + LEVESQUE + LEVIS + LE VISEUX + L'HOSPITAL + LHOSTE + LIGER + LIORET + LISQUES + LOISEAU + LOISELET + LONGUEVAL + LONGVILLIERS + LONNEL + L'ORFÃVRE + LORRAINE + LORRY + LOURDEREAU + LOUTRE + LOUVAIN + LOWEZ + LUCAS + LUFORT + LUSIGNAN + LUXEMBOURG + LUYTON +MACHY de COCQUEREL + MAGNY + MAHEUT + MAILLAULT + MAILLY + MALICORNE + MALLET + MALVAULT + MANDION + MANIGOT + MANIVOIRE + MANOURY + MARCHAIS (des) + MARCHAND + MARCHEVILLE + MARÃCHAL + MARTIN + MARTROIS + MARY + MASSE + MASSIET + MATHET + MATHIEU + MAUGRAS + MAUNOIR + MAUPETIT + MAY + MEHUN + MELLO + MELUN + MÃRANIE + MERAT + MERLE + MESTIVIER + MEULLENT + MEZ + MICHAUD + MIGNARD + MIGUET + MILLY + MINE + MIZIER + MOCQUOT + MOIREAU + MOISETTE + MOLEMBAIS + MOLIENS + MONCHY + MONTBELLIARD + MONTDIDIER + MONTFAUCON + MONTFERRAT + MONTFORT + MONTHOMER + MONTIGNY + MONTJAY + MONTLHÃRY + MONTMORENCY + MOREAU + MOREL + MOREUIL + MORILLON + MORIN + MOTHERE + MOUCY + MOULIN + MOUTON + MOVEN + MULLER +NAMUR + NANGIS + NANTEUIL + NASLOS + NAUDET + NAULIN + NÃDONCHEL + NEEL + NEMOURS + NESLE + NEUFMEZ + NEUVILLE + NEVERS + NIELLES + NOÃL + NOEUX + NORMANDIE +OCCRE + OISELAY + OLHAIN + OPPENOT + OSTREL + OSTRICQUE + OUDIN + OUTRELEAU +PACY + PAISAN + PAMPELUNE + PAQUIER + PARIS + PARMENTIER + PARTY + PASQUEAU + PASQUERON + PATE + PAULVE + PAVIAULT + PÃCHENOT + PENEL + PÃROT + PERRIGNON + PERRIGOT + PERRIN + PERROCHE + PERTAT + PERTHUIS + PESCHEUX + PETIT + PETITJEAN + PETITPAS + PEZà + PHILIPPON + PICARD + PICQUIGNY + PIENNES + PINAUD + PINET + PINGOT + PLESSIS + PLUSQUELLEC + POINLANE + POINTEAU + POIRIà + POISSON + POITIERS + POIX + POLLE + POLLET + POLLIARD + PONTHIEU + PONTROHART + PORCHEROT + POTHERAT + POUILLAUDE + POULAIN + POUPET + POURCHOT + PRÃAULX + PRETZ (des) + PRÃVOST + PROCHASSON + PROTARD + PROU + PRUVOST + QUAROUBLE + QUESNEL + QUESNES (des) + QUESNOY + QUINQUET + QUIRAULT +RANCON + RAPIN + RASOIR + RATILLON + RAULIN + RAVAULT + RAYNEVAL + REGNARD + REGNAULT + RELY + RENARD + RENOUX + RENVOYà + RETHEL + RICAMETZ + RIGOUT + RIMBERT + RIVELOIS + RIVERSE + ROBERT + ROBIN + ROBINET + ROBLOT + ROCHEFORT + ROEULX + ROGER + ROLLAINCOURT + RONNELLE + ROSE + ROSMADEC + ROTY + ROUCY + ROUHY + ROULLIER + ROUSSEAU + ROUSSEL + ROUSSELET + ROUSSET + ROY + ROYE + ROYER + RUETTE + RUSSIE +SABRAN + SACQUESPÃE + SAILLY + SAINT-BLIMOND + SAINT-ESPRIT + SAINT-GEORGES + SAINT-OMER + SAINT-PAUL + SAINT-VALERY + SAINT-VENANT + SAINT-VÃRAIN + SAINVILLE + SALIN + SALLEY + SANCERRE + SARS + SART + SAUSSERON + SAVARY + SAVERY + SAVOIE + SAXE + SECHELLES + SEGUIN + SEGUINOT + SENESTRE + SEURAT + SIMON + SODADE + SOICHET + SOISSONS + SOMAING + SOUABE + SOUDà + SOUGER + SOULHAC + SOYER + SPINOLA + STAVELE + STEUER + SULLY +TARTINVILLE + TELLIER + TÃNEVEAU + TENIERE + TENREMONDE + TESSEL + TESTAT + THIEMBRONNE + THIENNES + THIERN + THIERRY + THIES + THIEURY + THIMONIER + THOMAS + THOROTE + THUILLIER + THUREAU + TILLOU + TILLOY + TINGRY + TONNERRE + TOUCY + TOULOUSE + TOURMIGNIES + TRANCHELION + TRASIGNIES + TRAVES + TRECY + TREMBLAY + TRESSAULT + TRIBAUDAUT + TRIE + TRIVULCE + TROILLARD + TRUCHY + TUPINIER + TURENNE + TURQUIS + TYREL +VAAST + VARENTE + VASSE + VAUDEMONT + VAUDRICOURT + VEAU + VENDEUIL + VENDÃME + VENIZY + VERGNON + VERMANDOIS + VERMEILLES + VÃRON + VERROLOT + VIANDEN + VIAULT + VIEILLARD + VIENNE + VIENNOIS + VIGREUX + VILLAIN + VILLARD + VILLE + VILLEBÃON + VILLEHARDOUIN + VILTARD + VINCENT + VINÃON + VINOT + VIR + VITRà + VITUROT + VOUHEC + VOYSINES + WALLINS + WANDRINGHEM + WARGNY + WAVRANS + WAVRIN + XAVIER + YGER + YPRES + YSSELSTEIN + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/prenoms =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/prenoms (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/prenoms 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,101 @@ +Lucas +Theo +Hugo +Thomas +Enzo +Maxime +Alexandre +Mathis +Nathan +Antoine +Clement +Romain +Alexis +Louis +Quentin +Leo +Nicolas +Tom +Baptiste +Paul +Valentin +Arthur +Axel +Julien +Matteo +Matheo +Benjamin +Jules +Pierre +Yanis +Florian +Dylan +Raphael +Adrien +Corentin +Kevin +Mathieu +Maxence +Anthony +Victor +Noah +Gabriel +Killian +Simon +Guillaume +Dorian +Samuel +Bastien +Mohamed +Tristan +Vincent +Rayan +Jeremy +Martin +Kylian +Evan +Thibault +Ethan +Mateo +Remi +Erwan +Mael +Matthieu +Jordan +Damien +Antonin +Loic +Robin +Adam +Noe +Mathias +Aurelien +Titouan +Esteban +Ryan +Lenny +Yann +David +Mehdi +William +Bryan +Sacha +Mathys +Jonathan +Lilian +Thibaut +Logan +Noa +Gaetan +Jean +Charles +Alex +Gabin +Tony +Lorenzo +Alan +Arnaud +Sofiane +Amine +Marius + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/schema.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/schema.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/schema.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,314 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- + This is the Solr schema file. This file should be named "schema.xml" and + should be in the conf directory under the solr home + (i.e. ./solr/conf/schema.xml by default) + or located where the classloader for the Solr webapp can find it. + + This example schema is the recommended starting point for users. + It should be kept correct and concise, usable out-of-the-box. + + For more information, on how to customize this file, please see + http://wiki.apache.org/solr/SchemaXml +--> + +<schema name="wikitty" version="1.1"> + <!-- attribute "name" is the name of this schema and is only used for display purposes. + Applications should change this to reflect the nature of the search collection. + version="1.1" is Solr's version number for the schema syntax and semantics. It should + not normally be changed by applications. + 1.0: multiValued attribute did not exist, all fields are multiValued by nature + 1.1: multiValued attribute introduced, false by default --> + + <types> + <!-- field type definitions. The "name" attribute is + just a label to be used by field definitions. The "class" + attribute and any other attributes determine the real + behavior of the fieldType. + Class names starting with "solr" refer to java classes in the + org.apache.solr.analysis package. + --> + + <!-- The StrField type is not analyzed, but indexed/stored verbatim. + - StrField and TextField support an optional compressThreshold which + limits compression (if enabled in the derived fields) to values which + exceed a certain size (in characters). + --> + <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/> + + <!-- boolean type: "true" or "false" --> + <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/> + + <!-- The optional sortMissingLast and sortMissingFirst attributes are + currently supported on types that are sorted internally as strings. + - If sortMissingLast="true", then a sort on this field will cause documents + without the field to come after documents with the field, + regardless of the requested sort order (asc or desc). + - If sortMissingFirst="true", then a sort on this field will cause documents + without the field to come before documents with the field, + regardless of the requested sort order. + - If sortMissingLast="false" and sortMissingFirst="false" (the default), + then default lucene sorting will be used which places docs without the + field first in an ascending sort and last in a descending sort. + --> + + + <!-- numeric field types that store and index the text + value verbatim (and hence don't support range queries, since the + lexicographic ordering isn't equal to the numeric ordering) --> + <fieldType name="integer" class="solr.IntField" omitNorms="true"/> + <fieldType name="long" class="solr.LongField" omitNorms="true"/> + <fieldType name="float" class="solr.FloatField" omitNorms="true"/> + <fieldType name="double" class="solr.DoubleField" omitNorms="true"/> + + + <!-- Numeric field types that manipulate the value into + a string value that isn't human-readable in its internal form, + but with a lexicographic ordering the same as the numeric ordering, + so that range queries work correctly. --> + <fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/> + <fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/> + <fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/> + <fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/> + + + <!-- The format for this date field is of the form 1995-12-31T23:59:59Z, and + is a more restricted form of the canonical representation of dateTime + http://www.w3.org/TR/xmlschema-2/#dateTime + The trailing "Z" designates UTC time and is mandatory. + Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z + All other components are mandatory. + + Expressions can also be used to denote calculations that should be + performed relative to "NOW" to determine the value, ie... + + NOW/HOUR + ... Round to the start of the current hour + NOW-1DAY + ... Exactly 1 day prior to now + NOW/DAY+6MONTHS+3DAYS + ... 6 months and 3 days in the future from the start of + the current day + + Consult the DateField javadocs for more information. + --> + <fieldType name="date" class="solr.DateField" sortMissingLast="true" omitNorms="true"/> + + + <!-- The "RandomSortField" is not used to store or search any + data. You can declare fields of this type it in your schema + to generate psuedo-random orderings of your docs for sorting + purposes. The ordering is generated based on the field name + and the version of the index, As long as the index version + remains unchanged, and the same field name is reused, + the ordering of the docs will be consistent. + If you want differend psuedo-random orderings of documents, + for the same version of the index, use a dynamicField and + change the name + --> + <fieldType name="random" class="solr.RandomSortField" indexed="true" /> + + <!-- solr.TextField allows the specification of custom text analyzers + specified as a tokenizer and a list of token filters. Different + analyzers may be specified for indexing and querying. + + The optional positionIncrementGap puts space between multiple fields of + this type on the same document, with the purpose of preventing false phrase + matching across fields. + + For more info on customizing your analyzer chain, please see + http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters + --> + + <!-- One can also specify an existing Analyzer class that has a + default constructor via the class attribute on the analyzer element + <fieldType name="text_greek" class="solr.TextField"> + <analyzer class="org.apache.lucene.analysis.el.GreekAnalyzer"/> + </fieldType> + --> + + <!-- A text field that only splits on whitespace for exact matching of words --> + <fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100"> + <analyzer> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + </analyzer> + </fieldType> + + <!-- A text field that uses WordDelimiterFilter to enable splitting and matching of + words on case-change, alpha numeric boundaries, and non-alphanumeric chars, + so that a query of "wifi" or "wi fi" could match a document containing "Wi-Fi". + Synonyms and stopwords are customized by external files, and stemming is enabled. + Duplicate tokens at the same position (which may result from Stemmed Synonyms or + WordDelim parts) are removed. + --> + <fieldType name="text" class="solr.TextField" positionIncrementGap="100"> + <analyzer type="index"> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + <!-- in this example, we will only use synonyms at query time + <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/> + --> + <!-- Case insensitive stop word removal. + enablePositionIncrements=true ensures that a 'gap' is left to + allow for accurate phrase queries. + --> + <filter class="solr.StopFilterFactory" + ignoreCase="true" + words="stopwords.txt" + enablePositionIncrements="true" + /> + <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + <analyzer type="query"> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> + <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> + <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + </fieldType> + + <fieldType name="text_core" class="solr.TextField" positionIncrementGap="100"> + <analyzer> + <tokenizer class="solr.WhitespaceTokenizerFactory" /> + <filter class="solr.LowerCaseFilterFactory" /> + <!-- filter class="solr.WordDelimiterFilterFactory" + generateWordParts="1" generateNumberParts="1" + catenateWords="1" catenateNumbers="1" + catenateAll="0" splitOnCaseChange="1" / --> + </analyzer> + </fieldType> + + + <!-- Less flexible matching, but less false matches. Probably not ideal for product names, + but may be good for SKUs. Can insert dashes in the wrong place and still match. --> + <fieldType name="textTight" class="solr.TextField" positionIncrementGap="100" > + <analyzer> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/> + <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> + <filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + </fieldType> + + <!-- + Setup simple analysis for spell checking + --> + <fieldType name="textSpell" class="solr.TextField" positionIncrementGap="100" > + <analyzer> + <tokenizer class="solr.StandardTokenizerFactory"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + </fieldType> + + <!-- This is an example of using the KeywordTokenizer along + With various TokenFilterFactories to produce a sortable field + that does not include some properties of the source text + --> + <fieldType name="alphaOnlySort" class="solr.TextField" sortMissingLast="true" omitNorms="true"> + <analyzer> + <!-- KeywordTokenizer does no actual tokenizing, so the entire + input string is preserved as a single token + --> + <tokenizer class="solr.KeywordTokenizerFactory"/> + <!-- The LowerCase TokenFilter does what you expect, which can be + when you want your sorting to be case insensitive + --> + <filter class="solr.LowerCaseFilterFactory" /> + <!-- The TrimFilter removes any leading or trailing whitespace --> + <filter class="solr.TrimFilterFactory" /> + <!-- The PatternReplaceFilter gives you the flexibility to use + Java Regular expression to replace any sequence of characters + matching a pattern with an arbitrary replacement string, + which may include back refrences to portions of the orriginal + string matched by the pattern. + + See the Java Regular Expression documentation for more + infomation on pattern and replacement string syntax. + + http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/package-summary.html + --> + <filter class="solr.PatternReplaceFilterFactory" + pattern="([^a-z])" replacement="" replace="all" + /> + </analyzer> + </fieldType> + + <!-- since fields of this type are by default not stored or indexed, any data added to + them will be ignored outright + --> + <fieldtype name="ignored" stored="false" indexed="false" class="solr.StrField" /> + + </types> + + + <fields> + <field name="id" type="text" indexed="true" stored="true" required="true" /> + <field name="extensions" type="text" indexed="true" stored="false" multiValued="true"/> + + <!-- catchall field, containing all other searchable text fields (implemented + via copyField further on in this schema --> + <field name="text" type="text" indexed="true" stored="false" multiValued="true"/> + <copyField source="*_i" dest="text"/> + <copyField source="*_s" dest="text"/> + <copyField source="*_l" dest="text"/> + <copyField source="*_t" dest="text"/> + <copyField source="*_b" dest="text"/> + <copyField source="*_f" dest="text"/> + <copyField source="*_d" dest="text"/> + <copyField source="*_dt" dest="text"/> + + <dynamicField name="*_i" type="sint" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_l" type="slong" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_t" type="text" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_b" type="boolean" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_f" type="sfloat" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_d" type="sdouble" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_dt" type="date" indexed="true" stored="true" multiValued="true"/> + + <!-- all wikitty field --> + <dynamicField name="*" type="text" indexed="true" stored="true" multiValued="true"/> + + <!-- copy fields for optimisation --> + <dynamicField name="_*" type="text" indexed="true" stored="true" multiValued="true"/> + + </fields> + + <!-- Field to use to determine and enforce document uniqueness. + Unless this field is marked with required="false", it will be a required field + --> + <uniqueKey>id</uniqueKey> + + <!-- field for the QueryParser to use when an explicit fieldname is absent --> + <defaultSearchField>text</defaultSearchField> + + <!-- SolrQueryParser configuration: defaultOperator="AND|OR" --> + <solrQueryParser defaultOperator="AND"/> + +</schema> \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/selected-data.txt =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/selected-data.txt (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/selected-data.txt 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,200 @@ +Personne.civilite;Personne.nom;Personne.prenom;Personne.date_naissance;Personne.poids;Employe.matricule;Employe.arrivee;Employe.salaire +Me;BERTIN;Yann;1981-05-03T22:00:00.000Z;57;43055;2007-09-22T22:00:00.000Z;79336 +Mlle;ROSMADEC;Louis;1985-08-24T22:00:00.000Z;54;70520;1996-02-10T23:00:00.000Z;173509 +Mr;LADMIRAL;Louis;1960-08-08T23:00:00.000Z;89;28195;1993-12-07T23:00:00.000Z;69198 +Mr;BARBANÃON;Axel;1973-02-14T23:00:00.000Z;80;27213;2000-12-15T23:00:00.000Z;46860 +Mlle;WALLINS;Maxence;1954-11-15T23:00:00.000Z;58;38901;1997-07-01T22:00:00.000Z;98656 +Mr;DESCHAINTRE;Benjamin;1978-04-24T22:00:00.000Z;98;92969;2006-04-21T22:00:00.000Z;99393 +Me;LEVESIER;Jeremy;1951-10-23T23:00:00.000Z;70;47252;1994-10-13T23:00:00.000Z;21159 +Mr;CAILLAT;Victor;1954-09-24T23:00:00.000Z;109;57796;2003-04-10T22:00:00.000Z;28717 +Mlle;MELUN;Lenny;1978-04-12T22:00:00.000Z;67;10160;1990-10-27T23:00:00.000Z;144061 +Mlle;GRAÃAY;Matthieu;1972-12-26T23:00:00.000Z;66;21238;1991-12-01T23:00:00.000Z;63149 +Mr;SOUGER;Alexandre;1977-03-19T23:00:00.000Z;77;93241;2006-11-21T23:00:00.000Z;69679 +Mr;MIZIER;Erwan;1966-03-11T23:00:00.000Z;100;52809;2002-08-14T22:00:00.000Z;115885 +Mlle;TRUCHY;David;1950-04-06T23:00:00.000Z;54;79508;2008-05-23T22:00:00.000Z;60892 +Mlle;SAINT-VALERY;Erwan;1978-07-04T22:00:00.000Z;81;48898;1996-02-13T23:00:00.000Z;160815 +Mlle;BEUGNON;Arthur;1969-01-13T23:00:00.000Z;76;65870;1994-12-10T23:00:00.000Z;129076 +Me;ANJOU;Charles;1963-09-17T23:00:00.000Z;79;38272;2003-05-23T22:00:00.000Z;176419 +Mr;COLLET;Romain;1975-10-24T23:00:00.000Z;72;31031;2006-04-30T22:00:00.000Z;185145 +Me;THUREAU;Arnaud;1966-08-20T23:00:00.000Z;57;50163;1990-10-26T23:00:00.000Z;195053 +Mlle;PRÃAULX;Amine;1967-10-14T23:00:00.000Z;87;90929;1998-11-17T23:00:00.000Z;59874 +Mlle;AUCHOEL;Leo;1986-08-27T22:00:00.000Z;51;89775;2000-06-16T22:00:00.000Z;181027 +Mlle;BOICHOT;Damien;1952-04-13T23:00:00.000Z;51;93279;2005-11-23T23:00:00.000Z;68660 +Mr;TRAVES;Adrien;1960-04-06T23:00:00.000Z;92;32848;1995-02-03T23:00:00.000Z;95852 +Mlle;MERLE;Maxence;1989-07-02T22:00:00.000Z;66;77823;2004-01-25T23:00:00.000Z;132872 +Mr;GARES;Mathys;1980-06-27T22:00:00.000Z;69;60084;1992-11-17T23:00:00.000Z;124578 +Mr;CASTELLOISE;Alexis;1986-12-18T23:00:00.000Z;92;13249;2001-09-09T22:00:00.000Z;29929 +Mlle;GUENIN;Vincent;1978-06-01T22:00:00.000Z;80;93685;2003-03-16T23:00:00.000Z;187154 +Me;HARDENTHUN;Thomas;1989-09-23T22:00:00.000Z;56;98086;1991-12-20T23:00:00.000Z;187379 +Mr;LEROUX;Adrien;1955-09-02T23:00:00.000Z;99;61597;1991-03-01T23:00:00.000Z;121944 +Mr;GAUGUIER;Dylan;1950-08-04T23:00:00.000Z;62;29507;1999-08-31T22:00:00.000Z;180149 +Mr;COSSON;Titouan;1966-05-21T23:00:00.000Z;61;89408;1990-07-03T22:00:00.000Z;141060 +Mr;SAILLY;Anthony;1952-07-22T23:00:00.000Z;65;70628;1992-05-24T22:00:00.000Z;75856 +Mlle;VIENNOIS;Maxime;1960-02-02T23:00:00.000Z;68;40966;1995-02-03T23:00:00.000Z;158679 +Mlle;GRIMOIN;Robin;1966-08-13T23:00:00.000Z;64;17689;2004-03-10T23:00:00.000Z;140727 +Mr;CATHEU;Martin;1965-04-13T23:00:00.000Z;82;14271;2005-07-08T22:00:00.000Z;52071 +Mr;TRANCHELION;Mathieu;1983-12-25T23:00:00.000Z;84;67437;2004-05-19T22:00:00.000Z;199470 +Me;CHAUMERON;Amine;1965-06-27T23:00:00.000Z;58;19101;1998-02-16T23:00:00.000Z;150008 +Mlle;FONTY;Valentin;1980-07-11T22:00:00.000Z;75;77299;2006-02-03T23:00:00.000Z;76236 +Mlle;PONTROHART;Amine;1985-08-10T22:00:00.000Z;71;97231;2001-05-12T22:00:00.000Z;185410 +Me;DUCROT;Samuel;1981-05-01T22:00:00.000Z;80;19792;1993-07-08T22:00:00.000Z;131993 +Me;HÃRAT;Titouan;1972-07-25T23:00:00.000Z;90;81097;2001-08-10T22:00:00.000Z;144878 +Mr;COSSON;Mathias;1968-05-27T23:00:00.000Z;104;30556;1998-11-23T23:00:00.000Z;142768 +Me;VILLEBÃON;Sacha;1987-11-09T23:00:00.000Z;95;77133;2007-07-04T22:00:00.000Z;97465 +Me;BRISSIER;Yanis;1954-12-04T23:00:00.000Z;62;27697;2007-04-16T22:00:00.000Z;145951 +Me;LEDOUX;Paul;1982-11-19T23:00:00.000Z;63;25581;1991-07-09T22:00:00.000Z;181328 +Mlle;MELLO;Antonin;1980-06-10T22:00:00.000Z;85;36067;1996-08-25T22:00:00.000Z;193859 +Mlle;DUVEAU;Logan;1957-09-30T23:00:00.000Z;81;49279;1991-05-14T22:00:00.000Z;31666 +Me;LE MACHON;Remi;1968-06-03T23:00:00.000Z;52;12080;1999-08-01T22:00:00.000Z;181901 +Mlle;SEGUIN;Alexandre;1988-10-08T23:00:00.000Z;109;36816;2007-03-01T23:00:00.000Z;173650 +Me;POUILLAUDE;Alan;1970-12-15T23:00:00.000Z;104;37342;1998-05-12T22:00:00.000Z;113025 +Mr;BRILLE;Gabriel;1976-11-13T23:00:00.000Z;107;97371;1995-09-12T22:00:00.000Z;94803 +Mlle;GOUGEARD;Simon;1977-01-09T23:00:00.000Z;55;96559;2005-11-24T23:00:00.000Z;61970 +Me;GOFFERT;Nathan;1960-12-01T23:00:00.000Z;62;42040;2006-06-20T22:00:00.000Z;104683 +Mlle;MAGNY;Lucas;1964-08-01T23:00:00.000Z;97;56865;1999-01-24T23:00:00.000Z;142215 +Mlle;JANNETON;Jean;1966-07-12T23:00:00.000Z;82;22165;2005-10-06T22:00:00.000Z;140929 +Mlle;DELATTRE;Rayan;1966-04-30T23:00:00.000Z;69;96231;1996-12-07T23:00:00.000Z;154266 +Mr;HUBERT;Mael;1988-07-12T22:00:00.000Z;84;24073;2002-06-16T22:00:00.000Z;149328 +Mlle;WARGNY;Antonin;1987-08-20T22:00:00.000Z;103;10130;1995-04-16T22:00:00.000Z;50004 +Mr;GUISARME;Matthieu;1952-08-16T23:00:00.000Z;102;87868;1993-07-03T22:00:00.000Z;87810 +Mlle;BEUGNON;Arnaud;1952-10-18T23:00:00.000Z;98;74795;1991-02-15T23:00:00.000Z;125331 +Mr;DEMERY;Maxence;1960-12-10T23:00:00.000Z;104;46986;1993-08-27T22:00:00.000Z;60790 +Me;LAMY;Bastien;1959-09-21T23:00:00.000Z;71;85374;1996-10-01T22:00:00.000Z;105093 +Mr;HENRION;Leo;1959-07-17T23:00:00.000Z;75;45158;2002-08-07T22:00:00.000Z;131227 +Me;DESCAMPS;Antonin;1978-07-16T22:00:00.000Z;70;21409;1993-03-26T23:00:00.000Z;198251 +Me;DAIRE;Amine;1967-06-13T23:00:00.000Z;99;76095;2005-09-30T22:00:00.000Z;180051 +Mlle;SAINT-VÃRAIN;Alexis;1956-02-24T23:00:00.000Z;74;42660;1999-06-05T22:00:00.000Z;33367 +Mr;BOURGEOIS;Damien;1950-02-18T23:00:00.000Z;108;87838;2007-09-25T22:00:00.000Z;142162 +Mlle;POUILLAUDE;Clement;1964-03-08T23:00:00.000Z;81;23488;2004-03-09T23:00:00.000Z;44718 +Me;RETHEL;Thibaut;1970-09-10T23:00:00.000Z;87;67350;1998-12-07T23:00:00.000Z;100252 +Mr;NEEL;Thibaut;1986-09-30T23:00:00.000Z;54;73937;1996-05-31T22:00:00.000Z;40615 +Me;HABERT;Marius;1957-05-31T23:00:00.000Z;57;11628;1998-03-13T23:00:00.000Z;86571 +Mr;LESENNE;Quentin;1976-07-19T22:00:00.000Z;52;40756;2003-12-26T23:00:00.000Z;32011 +Mr;HUOT;Erwan;1978-11-18T23:00:00.000Z;70;69110;2006-09-16T22:00:00.000Z;177256 +Me;BOS;Guillaume;1962-05-26T23:00:00.000Z;61;10961;2000-05-25T22:00:00.000Z;159092 +Mlle;SAINVILLE;Quentin;1959-09-24T23:00:00.000Z;90;16188;2007-09-15T22:00:00.000Z;82030 +Mr;CHALON;Nicolas;1983-09-15T22:00:00.000Z;89;50498;2004-04-22T22:00:00.000Z;86063 +Mlle;TRUCHY;Erwan;1954-01-07T23:00:00.000Z;97;80010;2000-10-06T22:00:00.000Z;180010 +Me;VIAULT;Thomas;1983-10-07T23:00:00.000Z;51;60171;1991-07-01T22:00:00.000Z;87259 +Mr;MARCHAND;Dylan;1972-12-17T23:00:00.000Z;81;37413;2007-12-25T23:00:00.000Z;101822 +Mlle;PROU;Damien;1972-09-25T23:00:00.000Z;95;92314;1998-09-27T22:00:00.000Z;193288 +Mlle;ARLES;Yanis;1953-10-24T23:00:00.000Z;105;84330;1992-09-09T22:00:00.000Z;184634 +Mlle;GERMIGNY;Yanis;1978-01-22T23:00:00.000Z;67;31221;1993-06-22T22:00:00.000Z;20953 +Me;NEVERS;Maxence;1967-01-10T23:00:00.000Z;54;19354;2006-05-20T22:00:00.000Z;135170 +Mr;HAMELIN;Matthieu;1984-03-23T23:00:00.000Z;85;22647;2008-03-09T23:00:00.000Z;82530 +Mlle;GUERREAU;Titouan;1987-10-12T23:00:00.000Z;89;20969;1993-03-03T23:00:00.000Z;65772 +Mlle;CARRETTE;Lenny;1972-09-26T23:00:00.000Z;61;95507;1991-11-04T23:00:00.000Z;32555 +Me;SALIN;Noah;1976-04-06T22:00:00.000Z;54;34131;2005-06-14T22:00:00.000Z;21663 +Mr;BRISSIER;Tony;1979-02-26T23:00:00.000Z;74;63599;1998-08-13T22:00:00.000Z;55148 +Mlle;MARTIN;Samuel;1976-07-02T22:00:00.000Z;56;66926;1999-01-10T23:00:00.000Z;167574 +Me;GALVEUX;Erwan;1951-07-07T23:00:00.000Z;73;76635;1999-12-14T23:00:00.000Z;49168 +Mlle;RIGOUT;Lucas;1985-10-19T23:00:00.000Z;70;48252;1996-04-30T22:00:00.000Z;53915 +Mr;DUVEAU;Enzo;1960-01-12T23:00:00.000Z;75;94424;2000-01-16T23:00:00.000Z;178996 +Mr;GUINOT;Romain;1978-02-03T23:00:00.000Z;99;10551;2007-10-23T22:00:00.000Z;87533 +Me;JASQUIER;Dylan;1981-12-18T23:00:00.000Z;98;72083;2007-11-04T23:00:00.000Z;46309 +Mlle;VAUDEMONT;Adrien;1965-04-22T23:00:00.000Z;104;17604;1997-02-05T23:00:00.000Z;148219 +Me;MULLER;Robin;1984-05-11T22:00:00.000Z;82;92768;2006-01-11T23:00:00.000Z;134629 +Me;CARUE;Quentin;1979-02-12T23:00:00.000Z;100;49992;1991-10-19T23:00:00.000Z;159367 +Me;WAVRIN;Paul;1982-06-11T22:00:00.000Z;71;24903;1999-05-18T22:00:00.000Z;171847 +Mlle;PAQUIER;Maxime;1987-11-12T23:00:00.000Z;69;18694;1991-10-31T23:00:00.000Z;77541 +Me;CUSANI;Logan;1964-04-23T23:00:00.000Z;52;81187;1992-09-26T22:00:00.000Z;100143 +Mlle;CANDAVENE;Killian;1971-10-04T23:00:00.000Z;83;52664;1996-11-05T23:00:00.000Z;64601 +Mr;BERTIER;Adrien;1988-11-01T23:00:00.000Z;91;90375;1993-11-19T23:00:00.000Z;162036 +Mlle;LELEU;Valentin;1950-10-03T23:00:00.000Z;99;86818;2003-02-21T23:00:00.000Z;46301 +Me;COQUIBUS;Jeremy;1983-10-14T23:00:00.000Z;59;97664;2008-10-19T22:00:00.000Z;164894 +Me;DELATTRE;Remi;1981-02-12T23:00:00.000Z;72;75475;2006-07-25T22:00:00.000Z;169658 +Mr;FAUCONNIER;Valentin;1961-02-13T23:00:00.000Z;104;50831;2002-07-10T22:00:00.000Z;153609 +Mlle;MÃRANIE;Lorenzo;1967-10-12T23:00:00.000Z;79;80332;2004-01-15T23:00:00.000Z;35947 +Mlle;ROGER;Tony;1961-03-26T23:00:00.000Z;71;10172;2007-10-22T22:00:00.000Z;44000 +Mr;POINTEAU;Thibault;1962-06-20T23:00:00.000Z;53;52312;2002-02-02T23:00:00.000Z;74782 +Me;LENS;Julien;1951-04-21T23:00:00.000Z;87;13196;2008-06-12T22:00:00.000Z;186435 +Mr;TOURMIGNIES;Antoine;1976-08-05T22:00:00.000Z;83;35571;2001-12-03T23:00:00.000Z;130002 +Me;BLONDEL;Alex;1981-06-20T22:00:00.000Z;80;72004;1992-05-15T22:00:00.000Z;121923 +Me;CERF;Ryan;1987-09-23T22:00:00.000Z;71;67691;1999-08-23T22:00:00.000Z;173306 +Me;LE SAULX;Benjamin;1974-12-25T23:00:00.000Z;97;77500;1994-03-14T23:00:00.000Z;149697 +Me;OISELAY;Jonathan;1962-09-08T23:00:00.000Z;93;66251;2004-10-14T22:00:00.000Z;81881 +Mlle;COUDRET;Robin;1963-11-18T23:00:00.000Z;62;52638;2001-03-05T23:00:00.000Z;28147 +Me;GUILBERT;Mathias;1963-02-03T23:00:00.000Z;86;27123;1990-12-21T23:00:00.000Z;163877 +Mlle;BERTIN;Jeremy;1953-06-16T23:00:00.000Z;88;29245;2005-06-26T22:00:00.000Z;22624 +Me;THIEURY;Kylian;1975-04-01T23:00:00.000Z;76;77193;2002-07-13T22:00:00.000Z;190694 +Me;ROUSSET;Thibault;1956-05-18T23:00:00.000Z;54;20016;1996-04-12T22:00:00.000Z;23903 +Mlle;BÃTHENCOURT;Benjamin;1969-09-08T23:00:00.000Z;83;50644;2004-05-14T22:00:00.000Z;112436 +Mlle;RIMBERT;Noe;1969-08-11T23:00:00.000Z;93;38741;1992-08-18T22:00:00.000Z;82685 +Mr;NANTEUIL;Gabriel;1984-01-27T23:00:00.000Z;69;16845;2003-10-12T22:00:00.000Z;28252 +Mr;DAUVISSAT;Anthony;1964-11-24T23:00:00.000Z;102;31838;2002-09-24T22:00:00.000Z;128661 +Me;DREUX;Damien;1985-02-16T23:00:00.000Z;56;76645;1993-08-26T22:00:00.000Z;137468 +Mr;BELLEVAL;Matteo;1951-02-20T23:00:00.000Z;71;12615;2002-01-06T23:00:00.000Z;86806 +Me;BEAUPARISIS;Thibaut;1982-11-27T23:00:00.000Z;63;60842;1997-12-14T23:00:00.000Z;146243 +Mr;BLONDEL;Bryan;1955-02-18T23:00:00.000Z;97;64343;1991-09-03T22:00:00.000Z;165152 +Mlle;LECLAIR;Gabin;1979-08-21T22:00:00.000Z;100;19146;2006-07-13T22:00:00.000Z;171603 +Mlle;DUDOUT;Maxime;1988-12-23T23:00:00.000Z;73;98107;2006-04-26T22:00:00.000Z;180200 +Mr;LAURENT;Jeremy;1956-10-10T23:00:00.000Z;81;57055;1999-06-10T22:00:00.000Z;75744 +Mlle;HACK;Tristan;1954-12-22T23:00:00.000Z;74;81519;2008-04-09T22:00:00.000Z;71728 +Mr;BERNICOURT;Adrien;1953-06-15T23:00:00.000Z;65;32842;1996-10-22T22:00:00.000Z;100431 +Mlle;CALLEMENT;Damien;1979-06-07T22:00:00.000Z;63;93678;2000-08-21T22:00:00.000Z;75056 +Mlle;RENVOYÃ;Robin;1971-02-10T23:00:00.000Z;74;46689;2000-01-11T23:00:00.000Z;129880 +Mr;LONGUEVAL;Martin;1955-05-05T23:00:00.000Z;84;84869;2005-08-22T22:00:00.000Z;51793 +Mr;MAHEUT;Enzo;1957-08-18T23:00:00.000Z;88;88577;1995-01-20T23:00:00.000Z;69796 +Mr;MALVAULT;Paul;1965-07-09T23:00:00.000Z;97;63917;1995-01-22T23:00:00.000Z;84301 +Mlle;GAUCHER;Mathieu;1988-08-13T22:00:00.000Z;71;26125;1991-09-11T22:00:00.000Z;49168 +Mlle;ANJOU;Adam;1968-05-21T23:00:00.000Z;96;97790;2002-03-01T23:00:00.000Z;187057 +Me;BRAQUE;Simon;1959-01-06T23:00:00.000Z;84;28006;2002-07-16T22:00:00.000Z;120489 +Mr;CHASTILLON;Clement;1987-02-15T23:00:00.000Z;98;28573;1991-02-01T23:00:00.000Z;112732 +Mr;BARCELONE;Alex;1984-03-11T23:00:00.000Z;67;76729;1998-08-07T22:00:00.000Z;183919 +Me;BOURSIN;Mael;1978-02-20T23:00:00.000Z;92;78047;1996-03-18T23:00:00.000Z;195614 +Mlle;LONNEL;Yanis;1970-02-16T23:00:00.000Z;88;18206;1998-11-16T23:00:00.000Z;90963 +Mr;MILLY;Antonin;1959-10-13T23:00:00.000Z;97;90500;1994-12-01T23:00:00.000Z;47290 +Mlle;COLOMBAT;Titouan;1978-07-18T22:00:00.000Z;109;52123;2000-07-07T22:00:00.000Z;107769 +Me;MATHIEU;Victor;1986-02-18T23:00:00.000Z;105;63926;1990-12-20T23:00:00.000Z;81253 +Mr;CATHEU;Remi;1967-01-18T23:00:00.000Z;77;15981;1997-06-04T22:00:00.000Z;53975 +Mr;ESNE;Gabin;1986-08-02T22:00:00.000Z;53;15305;2004-05-23T22:00:00.000Z;124805 +Mlle;JOIGNY;Corentin;1954-02-25T23:00:00.000Z;77;84976;2004-09-11T22:00:00.000Z;51252 +Me;HÃRAT;William;1971-06-17T23:00:00.000Z;73;33905;1992-08-07T22:00:00.000Z;147923 +Mr;AUMALE;Alexis;1967-06-02T23:00:00.000Z;77;73203;1999-09-08T22:00:00.000Z;84203 +Mr;BLANDY;Louis;1951-07-19T23:00:00.000Z;64;54751;1992-01-13T23:00:00.000Z;179290 +Mlle;GROSPRÃ;Tom;1963-03-16T23:00:00.000Z;50;83286;2008-12-03T23:00:00.000Z;195078 +Me;GAUGUIER;Leo;1957-04-03T23:00:00.000Z;64;47948;1991-09-26T22:00:00.000Z;183926 +Me;BERNÃTRE;Nicolas;1956-08-21T23:00:00.000Z;100;40747;2004-07-07T22:00:00.000Z;161156 +Mr;DEVILLE;Yanis;1965-03-18T23:00:00.000Z;63;86453;1996-07-27T22:00:00.000Z;65175 +Mr;GUENIER;Enzo;1973-01-17T23:00:00.000Z;72;60673;1997-10-01T22:00:00.000Z;153588 +Mlle;MOREUIL;Samuel;1970-09-06T23:00:00.000Z;54;20742;1998-04-17T22:00:00.000Z;162396 +Mlle;MONTHOMER;Dorian;1984-12-25T23:00:00.000Z;70;51293;1993-04-21T22:00:00.000Z;182360 +Mr;LE CLEF;Axel;1975-02-03T23:00:00.000Z;51;35592;2001-12-12T23:00:00.000Z;154841 +Me;LECLAIR;Vincent;1986-12-09T23:00:00.000Z;63;18712;1998-05-10T22:00:00.000Z;70148 +Mlle;BERNARD;Anthony;1980-10-26T23:00:00.000Z;50;31620;2004-07-23T22:00:00.000Z;68242 +Mlle;LEJONG;Thibault;1955-08-27T23:00:00.000Z;74;70725;2002-06-17T22:00:00.000Z;142013 +Mlle;SAINT-VÃRAIN;Raphael;1951-04-09T23:00:00.000Z;106;29365;1993-01-13T23:00:00.000Z;128797 +Mlle;LECERF;Enzo;1988-11-26T23:00:00.000Z;61;75952;1996-09-12T22:00:00.000Z;63803 +Mr;BOSEVENT;Matheo;1971-10-01T23:00:00.000Z;68;28027;1997-03-19T23:00:00.000Z;81573 +Me;MONCHY;Rayan;1960-08-09T23:00:00.000Z;59;42784;2008-03-22T23:00:00.000Z;172168 +Me;QUESNES (des);Adam;1981-01-06T23:00:00.000Z;85;89091;2005-04-04T22:00:00.000Z;76803 +Me;BARAT de LA HAYE;Adam;1957-06-09T23:00:00.000Z;90;10110;1997-08-31T22:00:00.000Z;192798 +Mlle;TILLOY;Anthony;1987-04-09T22:00:00.000Z;103;11385;1991-06-14T22:00:00.000Z;146083 +Mlle;DURVILLE;Aurelien;1984-07-27T22:00:00.000Z;105;78213;1995-08-08T22:00:00.000Z;34157 +Mr;BIRAGUE;Erwan;1972-05-01T23:00:00.000Z;59;11023;2008-07-25T22:00:00.000Z;106437 +Mr;ROY;Kevin;1981-08-21T22:00:00.000Z;86;32513;2005-01-13T23:00:00.000Z;61396 +Mr;GUENIN;Arthur;1963-05-20T23:00:00.000Z;75;22275;2006-09-27T22:00:00.000Z;181530 +Mr;SAVOIE;Bastien;1973-02-01T23:00:00.000Z;68;15304;1997-11-15T23:00:00.000Z;113732 +Mr;LESENNE;Leo;1980-03-18T23:00:00.000Z;79;63797;2006-02-23T23:00:00.000Z;179267 +Mr;LE COURTOIS;Lenny;1958-08-25T23:00:00.000Z;101;57020;1990-08-18T22:00:00.000Z;59297 +Me;ASSIGNIES;Logan;1950-07-14T23:00:00.000Z;70;25023;1995-09-25T23:00:00.000Z;28599 +Mr;BERTIN;Lenny;1951-06-02T23:00:00.000Z;67;97776;1994-04-03T22:00:00.000Z;33089 +Me;PARIS;Ryan;1984-02-09T23:00:00.000Z;109;76452;1990-08-06T22:00:00.000Z;154810 +Me;RUETTE;Alexis;1978-03-17T23:00:00.000Z;57;94927;2002-11-27T23:00:00.000Z;27468 +Mr;La TRÃMOILLE;Jules;1989-03-13T23:00:00.000Z;102;59907;2008-09-07T22:00:00.000Z;94663 +Mlle;CORDES;Arthur;1961-05-25T23:00:00.000Z;109;58625;2000-10-25T22:00:00.000Z;35098 +Mr;ROLLAINCOURT;Julien;1953-05-04T23:00:00.000Z;89;44066;2006-06-22T22:00:00.000Z;176839 +Mr;WARGNY;Charles;1954-08-09T23:00:00.000Z;70;37439;1997-03-20T23:00:00.000Z;53945 +Me;HERBET;Benjamin;1986-11-19T23:00:00.000Z;85;18483;1995-10-22T23:00:00.000Z;157592 +Me;OCCRE;Logan;1980-05-04T22:00:00.000Z;95;92706;1991-02-23T23:00:00.000Z;60133 +Mr;THIEURY;Leo;1976-05-21T22:00:00.000Z;77;55690;1991-10-22T23:00:00.000Z;42312 +Me;LEJEUNE;Thibaut;1952-06-03T23:00:00.000Z;88;10192;2003-01-15T23:00:00.000Z;195630 +Mlle;BONNAFAU;Alexis;1981-03-22T23:00:00.000Z;90;39366;1994-12-25T23:00:00.000Z;134296 +Me;LAURENT;Gaetan;1985-03-26T23:00:00.000Z;91;45416;2006-06-08T22:00:00.000Z;163574 +Me;XAVIER;Theo;1959-09-04T23:00:00.000Z;90;32613;1996-08-01T22:00:00.000Z;114810 +Mlle;MARÃCHAL;Lenny;1965-04-16T23:00:00.000Z;63;84033;1995-04-20T22:00:00.000Z;43793 +Mr;NEUVILLE;Vincent;1954-02-18T23:00:00.000Z;85;64896;1993-07-27T22:00:00.000Z;64180 +Mlle;VEAU;Yann;1954-09-19T23:00:00.000Z;65;70080;2004-07-14T22:00:00.000Z;116228 +Mr;MAILLAULT;Nicolas;1951-01-08T23:00:00.000Z;67;24701;1995-03-15T23:00:00.000Z;91771 +Mlle;FOUET;Mathieu;1978-03-26T23:00:00.000Z;57;27735;2007-05-04T22:00:00.000Z;96903 +Mr;FOUILLAUX;Marius;1968-01-02T23:00:00.000Z;58;46865;2000-02-03T23:00:00.000Z;157401 Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/solrconfig.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/solrconfig.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/solrconfig.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,700 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<config> + <!-- Set this to 'false' if you want solr to continue working after it has + encountered an severe configuration error. In a production environment, + you may want solr to keep working even if one handler is mis-configured. + + You may also set this to false using by setting the system property: + -Dsolr.abortOnConfigurationError=false + --> + <abortOnConfigurationError>${solr.abortOnConfigurationError:true}</abortOnConfigurationError> + + <!-- Used to specify an alternate directory to hold all index data + other than the default ./data under the Solr home. + If replication is in use, this should match the replication configuration. --> + <dataDir>${solr.data.dir:./solr/data}</dataDir> + + + <indexDefaults> + <!-- Values here affect all index writers and act as a default unless overridden. --> + <useCompoundFile>false</useCompoundFile> + + <mergeFactor>10</mergeFactor> + <!-- + If both ramBufferSizeMB and maxBufferedDocs is set, then Lucene will flush based on whichever limit is hit first. + + --> + <!--<maxBufferedDocs>1000</maxBufferedDocs>--> + <!-- Tell Lucene when to flush documents to disk. + Giving Lucene more memory for indexing means faster indexing at the cost of more RAM + + If both ramBufferSizeMB and maxBufferedDocs is set, then Lucene will flush based on whichever limit is hit first. + + --> + <ramBufferSizeMB>32</ramBufferSizeMB> + <maxMergeDocs>2147483647</maxMergeDocs> + <maxFieldLength>10000</maxFieldLength> + <writeLockTimeout>1000</writeLockTimeout> + <commitLockTimeout>10000</commitLockTimeout> + + <!-- + Expert: Turn on Lucene's auto commit capability. + This causes intermediate segment flushes to write a new lucene + index descriptor, enabling it to be opened by an external + IndexReader. + NOTE: Despite the name, this value does not have any relation to Solr's autoCommit functionality + --> + <!--<luceneAutoCommit>false</luceneAutoCommit>--> + <!-- + Expert: + The Merge Policy in Lucene controls how merging is handled by Lucene. The default in 2.3 is the LogByteSizeMergePolicy, previous + versions used LogDocMergePolicy. + + LogByteSizeMergePolicy chooses segments to merge based on their size. The Lucene 2.2 default, LogDocMergePolicy chose when + to merge based on number of documents + + Other implementations of MergePolicy must have a no-argument constructor + --> + <!--<mergePolicy>org.apache.lucene.index.LogByteSizeMergePolicy</mergePolicy>--> + + <!-- + Expert: + The Merge Scheduler in Lucene controls how merges are performed. The ConcurrentMergeScheduler (Lucene 2.3 default) + can perform merges in the background using separate threads. The SerialMergeScheduler (Lucene 2.2 default) does not. + --> + <!--<mergeScheduler>org.apache.lucene.index.ConcurrentMergeScheduler</mergeScheduler>--> + + <!-- + This option specifies which Lucene LockFactory implementation to use. + + single = SingleInstanceLockFactory - suggested for a read-only index + or when there is no possibility of another process trying + to modify the index. + native = NativeFSLockFactory + simple = SimpleFSLockFactory + + (For backwards compatibility with Solr 1.2, 'simple' is the default + if not specified.) + --> + <lockType>single</lockType> + </indexDefaults> + + <mainIndex> + <!-- options specific to the main on-disk lucene index --> + <useCompoundFile>false</useCompoundFile> + <ramBufferSizeMB>32</ramBufferSizeMB> + <mergeFactor>10</mergeFactor> + <!-- Deprecated --> + <!--<maxBufferedDocs>1000</maxBufferedDocs>--> + <maxMergeDocs>2147483647</maxMergeDocs> + <maxFieldLength>10000</maxFieldLength> + + <!-- If true, unlock any held write or commit locks on startup. + This defeats the locking mechanism that allows multiple + processes to safely access a lucene index, and should be + used with care. + This is not needed if lock type is 'none' or 'single' + --> + <unlockOnStartup>false</unlockOnStartup> + </mainIndex> + + <!-- Enables JMX if and only if an existing MBeanServer is found, use + this if you want to configure JMX through JVM parameters. Remove + this to disable exposing Solr configuration and statistics to JMX. + + If you want to connect to a particular server, specify the agentId + e.g. <jmx agentId="myAgent" /> + + If you want to start a new MBeanServer, specify the serviceUrl + e.g <jmx serviceurl="service:jmx:rmi:///jndi/rmi://localhost:9999/solr" /> + + For more details see http://wiki.apache.org/solr/SolrJmx + --> + <jmx /> + + <!-- the default high-performance update handler --> + <updateHandler class="solr.DirectUpdateHandler2"> + + <!-- A prefix of "solr." for class names is an alias that + causes solr to search appropriate packages, including + org.apache.solr.(search|update|request|core|analysis) + --> + + <!-- Perform a <commit/> automatically under certain conditions: + maxDocs - number of updates since last commit is greater than this + maxTime - oldest uncommited update (in ms) is this long ago + <autoCommit> + <maxDocs>10000</maxDocs> + <maxTime>1000</maxTime> + </autoCommit> + --> + + <!-- The RunExecutableListener executes an external command. + exe - the name of the executable to run + dir - dir to use as the current working directory. default="." + wait - the calling thread waits until the executable returns. default="true" + args - the arguments to pass to the program. default=nothing + env - environment variables to set. default=nothing + --> + <!-- A postCommit event is fired after every commit or optimize command + <listener event="postCommit" class="solr.RunExecutableListener"> + <str name="exe">solr/bin/snapshooter</str> + <str name="dir">.</str> + <bool name="wait">true</bool> + <arr name="args"> <str>arg1</str> <str>arg2</str> </arr> + <arr name="env"> <str>MYVAR=val1</str> </arr> + </listener> + --> + <!-- A postOptimize event is fired only after every optimize command, useful + in conjunction with index distribution to only distribute optimized indicies + <listener event="postOptimize" class="solr.RunExecutableListener"> + <str name="exe">snapshooter</str> + <str name="dir">solr/bin</str> + <bool name="wait">true</bool> + </listener> + --> + + </updateHandler> + + + <query> + <!-- Maximum number of clauses in a boolean query... can affect + range or prefix queries that expand to big boolean + queries. An exception is thrown if exceeded. --> + <maxBooleanClauses>1024</maxBooleanClauses> + + + <!-- Cache used by SolrIndexSearcher for filters (DocSets), + unordered sets of *all* documents that match a query. + When a new searcher is opened, its caches may be prepopulated + or "autowarmed" using data from caches in the old searcher. + autowarmCount is the number of items to prepopulate. For LRUCache, + the autowarmed items will be the most recently accessed items. + Parameters: + class - the SolrCache implementation (currently only LRUCache) + size - the maximum number of entries in the cache + initialSize - the initial capacity (number of entries) of + the cache. (seel java.util.HashMap) + autowarmCount - the number of entries to prepopulate from + and old cache. + --> + <filterCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="128"/> + + <!-- queryResultCache caches results of searches - ordered lists of + document ids (DocList) based on a query, a sort, and the range + of documents requested. --> + <queryResultCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="32"/> + + <!-- documentCache caches Lucene Document objects (the stored fields for each document). + Since Lucene internal document ids are transient, this cache will not be autowarmed. --> + <documentCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="0"/> + + <!-- If true, stored fields that are not requested will be loaded lazily. + + This can result in a significant speed improvement if the usual case is to + not load all stored fields, especially if the skipped fields are large compressed + text fields. + --> + <enableLazyFieldLoading>true</enableLazyFieldLoading> + + <!-- Example of a generic cache. These caches may be accessed by name + through SolrIndexSearcher.getCache(),cacheLookup(), and cacheInsert(). + The purpose is to enable easy caching of user/application level data. + The regenerator argument should be specified as an implementation + of solr.search.CacheRegenerator if autowarming is desired. --> + <!-- + <cache name="myUserCache" + class="solr.LRUCache" + size="4096" + initialSize="1024" + autowarmCount="1024" + regenerator="org.mycompany.mypackage.MyRegenerator" + /> + --> + + <!-- An optimization that attempts to use a filter to satisfy a search. + If the requested sort does not include score, then the filterCache + will be checked for a filter matching the query. If found, the filter + will be used as the source of document ids, and then the sort will be + applied to that. + <useFilterForSortedQuery>true</useFilterForSortedQuery> + --> + + <!-- An optimization for use with the queryResultCache. When a search + is requested, a superset of the requested number of document ids + are collected. For example, if a search for a particular query + requests matching documents 10 through 19, and queryWindowSize is 50, + then documents 0 through 49 will be collected and cached. Any further + requests in that range can be satisfied via the cache. --> + <queryResultWindowSize>50</queryResultWindowSize> + + <!-- Maximum number of documents to cache for any entry in the + queryResultCache. --> + <queryResultMaxDocsCached>200</queryResultMaxDocsCached> + + <!-- This entry enables an int hash representation for filters (DocSets) + when the number of items in the set is less than maxSize. For smaller + sets, this representation is more memory efficient, more efficient to + iterate over, and faster to take intersections. --> + <HashDocSet maxSize="3000" loadFactor="0.75"/> + + <!-- a newSearcher event is fired whenever a new searcher is being prepared + and there is a current searcher handling requests (aka registered). --> + <!-- QuerySenderListener takes an array of NamedList and executes a + local query request for each NamedList in sequence. --> + <listener event="newSearcher" class="solr.QuerySenderListener"> + <arr name="queries"> + <lst> <str name="q">solr</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst> <str name="q">rocks</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst><str name="q">static newSearcher warming query from solrconfig.xml</str></lst> + </arr> + </listener> + + <!-- a firstSearcher event is fired whenever a new searcher is being + prepared but there is no current registered searcher to handle + requests or to gain autowarming data from. --> + <listener event="firstSearcher" class="solr.QuerySenderListener"> + <arr name="queries"> + <lst> <str name="q">fast_warm</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst><str name="q">static firstSearcher warming query from solrconfig.xml</str></lst> + </arr> + </listener> + + <!-- If a search request comes in and there is no current registered searcher, + then immediately register the still warming searcher and use it. If + "false" then all requests will block until the first searcher is done + warming. --> + <useColdSearcher>false</useColdSearcher> + + <!-- Maximum number of searchers that may be warming in the background + concurrently. An error is returned if this limit is exceeded. Recommend + 1-2 for read-only slaves, higher for masters w/o cache warming. --> + <maxWarmingSearchers>2</maxWarmingSearchers> + + </query> + + <!-- + Let the dispatch filter handler /select?qt=XXX + handleSelect=true will use consistent error handling for /select and /update + handleSelect=false will use solr1.1 style error formatting + --> + <requestDispatcher handleSelect="true" > + <!--Make sure your system has some authentication before enabling remote streaming! --> + <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" /> + + <!-- Set HTTP caching related parameters (for proxy caches and clients). + + To get the behaviour of Solr 1.2 (ie: no caching related headers) + use the never304="true" option and do not specify a value for + <cacheControl> + --> + <!-- <httpCaching never304="true"> --> + <httpCaching lastModifiedFrom="openTime" + etagSeed="Solr"> + <!-- lastModFrom="openTime" is the default, the Last-Modified value + (and validation against If-Modified-Since requests) will all be + relative to when the current Searcher was opened. + You can change it to lastModFrom="dirLastMod" if you want the + value to exactly corrispond to when the physical index was last + modified. + + etagSeed="..." is an option you can change to force the ETag + header (and validation against If-None-Match requests) to be + differnet even if the index has not changed (ie: when making + significant changes to your config file) + + lastModifiedFrom and etagSeed are both ignored if you use the + never304="true" option. + --> + <!-- If you include a <cacheControl> directive, it will be used to + generate a Cache-Control header, as well as an Expires header + if the value contains "max-age=" + + By default, no Cache-Control header is generated. + + You can use the <cacheControl> option even if you have set + never304="true" + --> + <!-- <cacheControl>max-age=30, public</cacheControl> --> + </httpCaching> + </requestDispatcher> + + + <!-- requestHandler plugins... incoming queries will be dispatched to the + correct handler based on the path or the qt (query type) param. + Names starting with a '/' are accessed with the a path equal to the + registered name. Names without a leading '/' are accessed with: + http://host/app/select?qt=name + If no qt is defined, the requestHandler that declares default="true" + will be used. + --> + <requestHandler name="standard" class="solr.SearchHandler" default="true"> + <!-- default values for query parameters --> + <lst name="defaults"> + <str name="echoParams">explicit</str> + <!-- + <int name="rows">10</int> + <str name="fl">*</str> + <str name="version">2.1</str> + --> + </lst> + </requestHandler> + + + <!-- DisMaxRequestHandler allows easy searching across multiple fields + for simple user-entered phrases. It's implementation is now + just the standard SearchHandler with a default query type + of "dismax". + see http://wiki.apache.org/solr/DisMaxRequestHandler + --> + <requestHandler name="dismax" class="solr.SearchHandler" > + <lst name="defaults"> + <str name="defType">dismax</str> + <str name="echoParams">explicit</str> + <float name="tie">0.01</float> + <str name="qf"> + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + </str> + <str name="pf"> + text^0.2 features^1.1 name^1.5 manu^1.4 manu_exact^1.9 + </str> + <str name="bf"> + ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3 + </str> + <str name="fl"> + id,name,price,score + </str> + <str name="mm"> + 2<-1 5<-2 6<90% + </str> + <int name="ps">100</int> + <str name="q.alt">*:*</str> + <!-- example highlighter config, enable per-query with hl=true --> + <str name="hl.fl">text features name</str> + <!-- for this field, we want no fragmenting, just highlighting --> + <str name="f.name.hl.fragsize">0</str> + <!-- instructs Solr to return the field itself if no query terms are + found --> + <str name="f.name.hl.alternateField">name</str> + <str name="f.text.hl.fragmenter">regex</str> <!-- defined below --> + </lst> + </requestHandler> + + <!-- Note how you can register the same handler multiple times with + different names (and different init parameters) + --> + <requestHandler name="partitioned" class="solr.SearchHandler" > + <lst name="defaults"> + <str name="defType">dismax</str> + <str name="echoParams">explicit</str> + <str name="qf">text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0</str> + <str name="mm">2<-1 5<-2 6<90%</str> + <!-- This is an example of using Date Math to specify a constantly + moving date range in a config... + --> + <str name="bq">incubationdate_dt:[* TO NOW/DAY-1MONTH]^2.2</str> + </lst> + <!-- In addition to defaults, "appends" params can be specified + to identify values which should be appended to the list of + multi-val params from the query (or the existing "defaults"). + + In this example, the param "fq=instock:true" will be appended to + any query time fq params the user may specify, as a mechanism for + partitioning the index, independent of any user selected filtering + that may also be desired (perhaps as a result of faceted searching). + + NOTE: there is *absolutely* nothing a client can do to prevent these + "appends" values from being used, so don't use this mechanism + unless you are sure you always want it. + --> + <lst name="appends"> + <str name="fq">inStock:true</str> + </lst> + <!-- "invariants" are a way of letting the Solr maintainer lock down + the options available to Solr clients. Any params values + specified here are used regardless of what values may be specified + in either the query, the "defaults", or the "appends" params. + + In this example, the facet.field and facet.query params are fixed, + limiting the facets clients can use. Faceting is not turned on by + default - but if the client does specify facet=true in the request, + these are the only facets they will be able to see counts for; + regardless of what other facet.field or facet.query params they + may specify. + + NOTE: there is *absolutely* nothing a client can do to prevent these + "invariants" values from being used, so don't use this mechanism + unless you are sure you always want it. + --> + <lst name="invariants"> + <str name="facet.field">cat</str> + <str name="facet.field">manu_exact</str> + <str name="facet.query">price:[* TO 500]</str> + <str name="facet.query">price:[500 TO *]</str> + </lst> + </requestHandler> + + + <!-- + Search components are registered to SolrCore and used by Search Handlers + + By default, the following components are avaliable: + + <searchComponent name="query" class="org.apache.solr.handler.component.QueryComponent" /> + <searchComponent name="facet" class="org.apache.solr.handler.component.FacetComponent" /> + <searchComponent name="mlt" class="org.apache.solr.handler.component.MoreLikeThisComponent" /> + <searchComponent name="highlight" class="org.apache.solr.handler.component.HighlightComponent" /> + <searchComponent name="debug" class="org.apache.solr.handler.component.DebugComponent" /> + + Default configuration in a requestHandler would look like: + <arr name="components"> + <str>query</str> + <str>facet</str> + <str>mlt</str> + <str>highlight</str> + <str>debug</str> + </arr> + + If you register a searchComponent to one of the standard names, that will be used instead. + To insert handlers before or after the 'standard' components, use: + + <arr name="first-components"> + <str>myFirstComponentName</str> + </arr> + + <arr name="last-components"> + <str>myLastComponentName</str> + </arr> + --> + + <!-- The spell check component can return a list of alternative spelling + suggestions. --> + <searchComponent name="spellcheck" class="solr.SpellCheckComponent"> + + <str name="queryAnalyzerFieldType">textSpell</str> + + <lst name="spellchecker"> + <str name="name">default</str> + <str name="field">spell</str> + <str name="spellcheckIndexDir">./spellchecker1</str> + + </lst> + <lst name="spellchecker"> + <str name="name">jarowinkler</str> + <str name="field">spell</str> + <!-- Use a different Distance Measure --> + <str name="distanceMeasure">org.apache.lucene.search.spell.JaroWinklerDistance</str> + <str name="spellcheckIndexDir">./spellchecker2</str> + + </lst> + + <lst name="spellchecker"> + <str name="classname">solr.FileBasedSpellChecker</str> + <str name="name">file</str> + <str name="sourceLocation">spellings.txt</str> + <str name="characterEncoding">UTF-8</str> + <str name="spellcheckIndexDir">./spellcheckerFile</str> + </lst> + </searchComponent> + + <!-- a request handler utilizing the spellcheck component --> + <requestHandler name="/spellCheckCompRH" class="solr.SearchHandler"> + <lst name="defaults"> + <!-- omp = Only More Popular --> + <str name="spellcheck.onlyMorePopular">false</str> + <!-- exr = Extended Results --> + <str name="spellcheck.extendedResults">false</str> + <!-- The number of suggestions to return --> + <str name="spellcheck.count">1</str> + </lst> + <arr name="last-components"> + <str>spellcheck</str> + </arr> + </requestHandler> + + <!-- a search component that enables you to configure the top results for + a given query regardless of the normal lucene scoring.--> + +<!-- poussin 20090902 remove elevate this file is empty, what need ? + <searchComponent name="elevator" class="solr.QueryElevationComponent" > + <str name="queryFieldType">string</str> + <str name="config-file">elevate.xml</str> + </searchComponent> + --> + <!-- a request handler utilizing the elevator component --> +<!-- + <requestHandler name="/elevate" class="solr.SearchHandler" startup="lazy"> + <lst name="defaults"> + <str name="echoParams">explicit</str> + </lst> + <arr name="last-components"> + <str>elevator</str> + </arr> + </requestHandler> + --> + + <!-- Update request handler. + + Note: Since solr1.1 requestHandlers requires a valid content type header if posted in + the body. For example, curl now requires: -H 'Content-type:text/xml; charset=utf-8' + The response format differs from solr1.1 formatting and returns a standard error code. + + To enable solr1.1 behavior, remove the /update handler or change its path + --> + <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" /> + + <!-- + Analysis request handler. Since Solr 1.3. Use to returnhow a document is analyzed. Useful + for debugging and as a token server for other types of applications + --> + <requestHandler name="/analysis" class="solr.AnalysisRequestHandler" /> + + + <!-- CSV update handler, loaded on demand --> + <requestHandler name="/update/csv" class="solr.CSVRequestHandler" startup="lazy" /> + + + <!-- + Admin Handlers - This will register all the standard admin RequestHandlers. Adding + this single handler is equivolent to registering: + + <requestHandler name="/admin/luke" class="org.apache.solr.handler.admin.LukeRequestHandler" /> + <requestHandler name="/admin/system" class="org.apache.solr.handler.admin.SystemInfoHandler" /> + <requestHandler name="/admin/plugins" class="org.apache.solr.handler.admin.PluginInfoHandler" /> + <requestHandler name="/admin/threads" class="org.apache.solr.handler.admin.ThreadDumpHandler" /> + <requestHandler name="/admin/properties" class="org.apache.solr.handler.admin.PropertiesRequestHandler" /> + <requestHandler name="/admin/file" class="org.apache.solr.handler.admin.ShowFileRequestHandler" > + + If you wish to hide files under ${solr.home}/conf, explicitly register the ShowFileRequestHandler using: + <requestHandler name="/admin/file" class="org.apache.solr.handler.admin.ShowFileRequestHandler" > + <lst name="invariants"> + <str name="hidden">synonyms.txt</str> + <str name="hidden">anotherfile.txt</str> + </lst> + </requestHandler> + --> + <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" /> + + <!-- ping/healthcheck --> + <requestHandler name="/admin/ping" class="PingRequestHandler"> + <lst name="defaults"> + <str name="qt">standard</str> + <str name="q">solrpingquery</str> + <str name="echoParams">all</str> + </lst> + </requestHandler> + + <!-- Echo the request contents back to the client --> + <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" > + <lst name="defaults"> + <str name="echoParams">explicit</str> <!-- for all params (including the default etc) use: 'all' --> + <str name="echoHandler">true</str> + </lst> + </requestHandler> + + <highlighting> + <!-- Configure the standard fragmenter --> + <!-- This could most likely be commented out in the "default" case --> + <fragmenter name="gap" class="org.apache.solr.highlight.GapFragmenter" default="true"> + <lst name="defaults"> + <int name="hl.fragsize">100</int> + </lst> + </fragmenter> + + <!-- A regular-expression-based fragmenter (f.i., for sentence extraction) --> + <fragmenter name="regex" class="org.apache.solr.highlight.RegexFragmenter"> + <lst name="defaults"> + <!-- slightly smaller fragsizes work better because of slop --> + <int name="hl.fragsize">70</int> + <!-- allow 50% slop on fragment sizes --> + <float name="hl.regex.slop">0.5</float> + <!-- a basic sentence pattern --> + <str name="hl.regex.pattern">[-\w ,/\n\"']{20,200}</str> + </lst> + </fragmenter> + + <!-- Configure the standard formatter --> + <formatter name="html" class="org.apache.solr.highlight.HtmlFormatter" default="true"> + <lst name="defaults"> + <str name="hl.simple.pre"><![CDATA[<em>]]></str> + <str name="hl.simple.post"><![CDATA[</em>]]></str> + </lst> + </formatter> + </highlighting> + + + <!-- queryResponseWriter plugins... query responses will be written using the + writer specified by the 'wt' request parameter matching the name of a registered + writer. + The "default" writer is the default and will be used if 'wt' is not specified + in the request. XMLResponseWriter will be used if nothing is specified here. + The json, python, and ruby writers are also available by default. + + <queryResponseWriter name="xml" class="org.apache.solr.request.XMLResponseWriter" default="true"/> + <queryResponseWriter name="json" class="org.apache.solr.request.JSONResponseWriter"/> + <queryResponseWriter name="python" class="org.apache.solr.request.PythonResponseWriter"/> + <queryResponseWriter name="ruby" class="org.apache.solr.request.RubyResponseWriter"/> + <queryResponseWriter name="php" class="org.apache.solr.request.PHPResponseWriter"/> + <queryResponseWriter name="phps" class="org.apache.solr.request.PHPSerializedResponseWriter"/> + + <queryResponseWriter name="custom" class="com.example.MyResponseWriter"/> + --> + + <!-- XSLT response writer transforms the XML output by any xslt file found + in Solr's conf/xslt directory. Changes to xslt files are checked for + every xsltCacheLifetimeSeconds. + --> + <queryResponseWriter name="xslt" class="org.apache.solr.request.XSLTResponseWriter"> + <int name="xsltCacheLifetimeSeconds">5</int> + </queryResponseWriter> + + <queryParser name="wikitty" class="org.sharengo.wikitty.solr.WikittyQueryParser"/> + + + <!-- example of registering a query parser + <queryParser name="lucene" class="org.apache.solr.search.LuceneQParserPlugin"/> + --> + + <!-- example of registering a custom function parser + <valueSourceParser name="myfunc" class="com.mycompany.MyValueSourceParser" /> + --> + + <!-- config for the admin interface --> + <admin> + <defaultQuery>solr</defaultQuery> + + <!-- configure a healthcheck file for servers behind a loadbalancer + <healthcheck type="file">server-enabled</healthcheck> + --> + </admin> + +</config> Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/stopwords.txt =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/stopwords.txt (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/stopwords.txt 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +#Standard english stop words taken from Lucene's StopAnalyzer +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +s +such +t +that +the +their +then +there +these +they +this +to +was +will +with + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/testData.txt =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/testData.txt (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-jdbc-impl/src/test/resources/testData.txt 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,21 @@ + +extension Personne { + String nom, + String prenom, + Date date_naissance, + Numeric poids, + Boolean marie +} + +extension Employe { + Date arrivee, + String matricule, + Numeric salaire +} + +data { + Personne : + DufrÃĒne, Guillaume, 23/01/1982, 66, true + Employe : + 01/04/2008, 623541, 82564 +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/pom.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/pom.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/pom.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,100 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty-solr-impl</artifactId> + + <parent> + <groupId>org.sharengo.wikengo</groupId> + <artifactId>core-wikitty</artifactId> + <version>1.0.0-alpha-2</version> + </parent> + + <dependencies> + <!-- COMPILE --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>core-wikitty-api</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + + <!-- SOLR --> + <dependency> + <groupId>org.apache.solr</groupId> + <artifactId>solr-core</artifactId> + <version>1.3.0</version> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + <version>1.1.1</version> + </dependency> + + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>org.sharengo.wikengo.core-wikitty-solr-impl</name> + + <description>hbase impl of wikitty</description> + <inceptionYear>2009</inceptionYear> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>jar</packaging> + + <properties> + <maven.test.skip>true</maven.test.skip> + <maven.test.failure.ignore>true</maven.test.failure.ignore> + </properties> + + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + + <!--repositories> + <repository> + <id>sharengo-maven2-repository</id> + <name>Sharengo's repository</name> + <url>http://maven2.sharengo.org</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>warn</checksumPolicy> + </releases> + </repository> + </repositories--> + +</project> + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/Restriction2Solr.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/Restriction2Solr.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/Restriction2Solr.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,387 @@ +package org.sharengo.wikitty.solr; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.sharengo.wikitty.WikittyException; +import org.sharengo.wikitty.search.And; +import org.sharengo.wikitty.search.AssociatedRestriction; +import org.sharengo.wikitty.search.Between; +import org.sharengo.wikitty.search.Contains; +import org.sharengo.wikitty.search.Element; +import org.sharengo.wikitty.search.EndsWith; +import org.sharengo.wikitty.search.Equals; +import org.sharengo.wikitty.search.Greater; +import org.sharengo.wikitty.search.GreaterOrEqual; +import org.sharengo.wikitty.search.In; +import org.sharengo.wikitty.search.Keyword; +import org.sharengo.wikitty.search.Less; +import org.sharengo.wikitty.search.LessOrEqual; +import org.sharengo.wikitty.search.Not; +import org.sharengo.wikitty.search.NotEquals; +import org.sharengo.wikitty.search.Or; +import org.sharengo.wikitty.search.Restriction; +import org.sharengo.wikitty.search.RestrictionHelper; +import org.sharengo.wikitty.search.StartsWith; + +/** + * @author "Nicolas Chapurlat" <nicolas.chapurlat@logica.com> + * @author "Guillaume DufrÃĒne" <dufrene@argia.fr> + * + * This class is used to parse Restriction to create lucene request on + * content. Every operators describe in RestrictionName is handle. Parsing may + * throw exception when restriction parameters are incorrect. + */ +public class Restriction2Solr { + + private static final int MAX_SUBQUERY_RESULT = 100; + + /** use to permit client to modify fieldname during query generation */ + static public interface FieldModifier { + public String convertToSolr(String fieldname); + public String convertToField(String solrName); + } + final static protected FieldModifier dummyFieldModifier = new FieldModifier() { + public String convertToSolr(String fieldname) { + return fieldname; + } + public String convertToField(String solrName) { + return solrName; + } + }; + + protected FieldModifier fieldModifer; + + public Restriction2Solr() { + this(dummyFieldModifier); + } + + public Restriction2Solr(FieldModifier fieldModifer) { + this.fieldModifer = fieldModifer; + } + + public String toSolr(Restriction restriction) { + return toSolr(restriction, null); + } + + public String toSolr(Restriction restriction, SolrServer solr) + throws WikittyException { + // ParameterValidator.checkNullParameter(restriction, "restriction"); + switch (restriction.getName()) { + case TRUE: + return true2solr(); + case FALSE: + return false2solr(); + case NOT: + Not not = (Not) restriction; + return not2solr(not); + case AND: + And and = (And) restriction; + return and2solr(and); + case OR: + Or or = (Or) restriction; + return or2solr(or); + case EQUALS: + Equals eq = (Equals) restriction; + return eq2solr(eq); + case NOT_EQUALS: + NotEquals neq = (NotEquals) restriction; + return neq2solr(neq); + case LESS: + Less less = (Less) restriction; + return less2solr(less); + case LESS_OR_EQUAL: + LessOrEqual lessEq = (LessOrEqual) restriction; + return lessEq2solr(lessEq); + case GREATER: + Greater great = (Greater) restriction; + return great2solr(great); + case GREATER_OR_EQUAL: + GreaterOrEqual greatEq = (GreaterOrEqual) restriction; + return greatEq2solr(greatEq); + case BETWEEN: + Between between = (Between) restriction; + return between2solr(between); + case CONTAINS: + Contains contains = (Contains) restriction; + return contains2solr(contains); + case IN: + In in = (In) restriction; + return in2solr(in); + case STARTS_WITH: + StartsWith start = (StartsWith) restriction; + return start2solr(start); + case ENDS_WITH: + EndsWith end = (EndsWith) restriction; + return end2solr(end); + case ASSOCIATED: + AssociatedRestriction associated = (AssociatedRestriction) restriction; + return associated2solr(associated, solr); + case KEYWORD: + Keyword keyword = (Keyword) restriction; + return keyword2solr(keyword); + default: + throw new WikittyException("this kind of restriction is not supported : " + + restriction.getName().toString()); + } + } + + private String in2solr(In in) { + boolean first = true; + String result = in.getElement().getName() + ":["; + for( String value : in.getValue() ) { + if ( !first ) { result += ", "; first = false; } + result += value; + } + result +="]"; + return result; + } + + private String associated2solr(AssociatedRestriction associated, SolrServer solr) throws WikittyException { + String subQuery = toSolr( associated.getRestriction() ); + SolrQuery query = new SolrQuery(WikittySearchEngineSolr.SOLR_QUERY_PARSER + subQuery); + query.setRows(MAX_SUBQUERY_RESULT); + QueryResponse resp = null; + try { + resp = solr.query(query); + } catch (SolrServerException e) { + throw new WikittyException("Unable to execute associative query on " + associated.getElement().getName(), e); + } + SolrDocumentList solrResults = resp.getResults(); + + Restriction generatedRestriction = null; + long size = solrResults.size(); + if ( size == 0 ) { + throw new WikittyException("Associated " + associated.getElement().getName() + " do not retrieved any result"); + } + if ( size == 1 ) { + generatedRestriction = RestrictionHelper.eq( associated.getElement(), (String) solrResults.get(0).getFieldValue(WikittySearchEngineSolr.SOLR_ID) ); + } else { + List<String> ids = new ArrayList<String>(solrResults.size()); + for (SolrDocument doc : solrResults) { + String id = (String) doc.getFieldValue(WikittySearchEngineSolr.SOLR_ID); + ids.add(id); + } + generatedRestriction = new In(associated.getElement(), ids); + } + Restriction parent = associated.getParentRestrictionDto(); + And and; + if ( parent instanceof And ) { + and = (And) parent; + and.getRestrictions().add( generatedRestriction ); + } else { + and = RestrictionHelper.and( Arrays.asList(new Restriction[]{ associated.getParentRestrictionDto(), generatedRestriction }) ); + } + return toSolr(and); + } + + private String not2solr(Not not) throws WikittyException { + if (not.getRestriction() == null) { + throw new WikittyException( "not.restriction" ); + } + return "( *:* - " + toSolr(not.getRestriction()) + " )"; + } + + private String and2solr(And and) throws WikittyException { + if (and.getRestrictions() == null) { + throw new WikittyException( "and.restrictions is null" ); + } + if (and.getRestrictions().size() < 2) { + throw new WikittyException( "AND is an operator that handle 2 operand at least"); + } + boolean first = true; + StringBuffer result = new StringBuffer(); + for (Restriction restriction : and.getRestrictions()) { + if (first) { + result.append("( ").append(toSolr(restriction)); + first = false; + } else { + result.append(" AND ").append(toSolr(restriction)); + } + } + return result.append(" )").toString(); + } + + private String or2solr(Or or) throws WikittyException { + if (or.getRestrictions() == null) { + throw new WikittyException("or.restrictions is null"); + } + if (or.getRestrictions().size() < 2) { + throw new WikittyException("OR is an operator that handle 2 operand at least"); + } + boolean first = true; + StringBuffer result = new StringBuffer(); + for (Restriction restriction : or.getRestrictions()) { + if (first) { + result.append("( "); + first = false; + } else { + result.append(" OR "); + } + result.append(toSolr(restriction)); + } + return result.append(" )").toString(); + } + + private String eq2solr(Equals eq) throws WikittyException { + return element2solr(eq.getElement()) + ":" + value2solr(eq.getValue()); + } + + private String neq2solr(NotEquals neq) + throws WikittyException { + return "-" + element2solr(neq.getElement()) + ":" + + value2solr(neq.getValue()); + } + + private String less2solr(Less less) throws WikittyException { + return element2solr(less.getElement()) + ":{* TO " + + value2solr(less.getValue()) + "}"; + } + + private String lessEq2solr(LessOrEqual lessEq) + throws WikittyException { + return element2solr(lessEq.getElement()) + ":[* TO " + + value2solr(lessEq.getValue()) + "]"; + } + + private String great2solr(Greater great) + throws WikittyException { + return element2solr(great.getElement()) + ":{" + + value2solr(great.getValue()) + " TO *}"; + } + + private String greatEq2solr(GreaterOrEqual greatEq) + throws WikittyException { + return element2solr(greatEq.getElement()) + ":[" + + value2solr(greatEq.getValue()) + " TO *]"; + } + + private String between2solr(Between between) + throws WikittyException { + if (between.getElement() == null) { + throw new WikittyException("contains.element"); + } + if (between.getMin() == null) { + throw new WikittyException("contains.min"); + } + if (between.getMax() == null) { + throw new WikittyException("contains.max"); + } + return element2solr(between.getElement()) + ":[" + + value2solr(between.getMin()) + " TO " + + value2solr(between.getMax()) + "]"; + } + + private String contains2solr(Contains contains) + throws WikittyException { + if (contains.getElement() == null) { + throw new WikittyException("contains.element"); + } + if (contains.getValue() == null) { + throw new WikittyException("contains.values"); + } + if (contains.getValue().size() < 1) { + throw new WikittyException("CONTAINS is an operator that handle 1 operand at least"); + } + + String operand = ""; + StringBuffer result = new StringBuffer(); + result.append("("); + for (String value : contains.getValue()) { + result.append(operand); + result.append(element2solr(contains.getElement())) + .append(":").append(value2solr(value)); + operand = " OR "; + } + result.append(")"); + return result.toString(); + } + + private String start2solr(StartsWith start) + throws WikittyException { + return element2solr(start.getElement()) + ":" + + value2solr(start.getValue(), true, false); + } + + private String end2solr(EndsWith end) { + return element2solr(end.getElement()) + ":" + value2solr(end.getValue()); + } + + private String true2solr() { + return "( *:* )"; + } + + private String false2solr() { + return "( *:* - *:* )"; + } + + private String keyword2solr(Keyword keyword) { + return value2solr(keyword.getValue()); + } + + private String value2solr(String value) { + return value2solr(value, false, false); + } + + private String value2solr(String value, boolean starOnEnd, + boolean revert) { + String result; + if (value != null) { + if (value.equals("*")) { + return "*"; + } + + if (revert) { + result = Restriction2Solr.escapeValue(reverse(value)); + } else { + result = Restriction2Solr.escapeValue(value); + } + } else { + result = ""; + } + if (starOnEnd) { + result += "*"; + } + if (result.contains(" ")) { + result = "\"" + result + "\""; + } + return result; + } + + private String element2solr(Element element) throws WikittyException { + String result = element.getName(); + if(Element.ELT_EXTENSION.equals(result)) { + result = WikittySearchEngineSolr.SOLR_EXTENSIONS; + } else if(Element.ELT_ID.equals(result)) { + result = WikittySearchEngineSolr.SOLR_ID; + } else { + result = element.getName(); + } + result = fieldModifer.convertToSolr(result); + return result; + } + + private static String escapeValue(String value) { + final String LUCENE_REPLACE_PATTERN = "\\+" + "|-" + "|&&" + "|\\|" + + "|!" + "|\\(|\\)" + "|\\[|\\]" + "|\\{|\\}" + "|\"" + "|:"; + return value.replaceAll(LUCENE_REPLACE_PATTERN, "\\\\$0"); + } + + private String reverse(String source) { + int i, len = source.length(); + StringBuffer dest = new StringBuffer(len); + + for (i = (len - 1); i >= 0; i--) { + dest.append(source.charAt(i)); + } + return dest.toString(); + } +} + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittyQueryParser.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittyQueryParser.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittyQueryParser.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,72 @@ +package org.sharengo.wikitty.solr; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.search.Query; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.search.LuceneQParserPlugin; +import org.apache.solr.search.QParser; +import org.apache.solr.search.QueryParsing; +import org.apache.solr.search.SolrQueryParser; + +/** + * Add allow leading wildcard + * setAllowLeadingWildcard(true); + * <br>Example: <code>{!wikitty q.op=AND df=text sort='price asc'}myfield:foo +bar -baz</code> + * More information @see LuceneQParserPlugin + */ +public class WikittyQueryParser extends LuceneQParserPlugin { + + public static String NAME = "wikitty"; + + @Override + public void init(NamedList args) { + } + + @Override + public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) { + return new SolrQParser(qstr, localParams, params, req); + } +} + +class SolrQParser extends QParser { + + static private Log log = LogFactory.getLog(SolrQParser.class); + String sortStr; + SolrQueryParser lparser; + + public SolrQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) { + super(qstr, localParams, params, req); + } + + @Override + public Query parse() throws ParseException { + + String defaultField = getParam(CommonParams.DF); + if(defaultField == null) { + defaultField = "text"; + } + + lparser = new SolrQueryParser(this, defaultField); + lparser.setAllowLeadingWildcard(true); + + String opParam = getParam(QueryParsing.OP); + if (opParam != null) { + lparser.setDefaultOperator("AND".equals(opParam) ? QueryParser.Operator.AND : QueryParser.Operator.OR); + } + + String qstr = getString(); + log.debug("Query parse : " + qstr); + return lparser.parse(qstr); + } + + @Override + public String[] getDefaultHighlightFields() { + return new String[]{lparser.getField()}; + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittySearchEngineSolr.java =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittySearchEngineSolr.java (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/java/org/sharengo/wikitty/solr/WikittySearchEngineSolr.java 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,712 @@ +/* *##% + * Copyright (c) 2009 poussin. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *##%*/ + +package org.sharengo.wikitty.solr; + + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.core.CoreContainer; +import org.nuiton.util.FileUtil; +import org.sharengo.wikitty.Criteria; +import org.sharengo.wikitty.FacetTopic; +import org.sharengo.wikitty.FieldType; +import org.sharengo.wikitty.FieldType.TYPE; +import org.sharengo.wikitty.PagedResult; +import org.sharengo.wikitty.TreeNode; +import org.sharengo.wikitty.UpdateResponse; +import org.sharengo.wikitty.Wikitty; +import org.sharengo.wikitty.WikittyException; +import org.sharengo.wikitty.WikittyExtension; +import org.sharengo.wikitty.WikittyExtensionStorage; +import org.sharengo.wikitty.WikittySearchEngine; +import org.sharengo.wikitty.WikittyTransaction; +import org.sharengo.wikitty.search.Search; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittySearchEngineSolr implements WikittySearchEngine { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittySearchEngineSolr.class); + + /** id field in solr */ + static final protected String SOLR_ID = "id"; + + /** extensions field name in solr */ + static final public String SOLR_EXTENSIONS = "extensions"; + + /** extension use to store field without extension to search on all extesnion */ + static final public String SOLR_ALL_EXTENSIONS = "all"; + + /** Precise the query parser to use, is allow leading wildcard */ + static final public String SOLR_QUERY_PARSER = "{!wikitty}"; + + // Use for indexation tree node + static final public String TREENODE_PREFIX = TreeNode.EXT_TREENODE + "."; + static final public String TREENODE_CHILD = TREENODE_PREFIX + "wikittyId"; + static final public String TREENODE_EMPTY = TREENODE_PREFIX + "empty"; + static final public String TREENODE_ROOT = TREENODE_PREFIX + "root"; + static final public String TREENODE_PATH = TREENODE_PREFIX + "path"; + + static protected class CommandSolr implements Command { + /** if is store command toStore is true, if is delete toStore is false */ + boolean toStore; + String id; + Wikitty wikitty; + /** use to store command */ + public CommandSolr(Wikitty wikitty) { + this.wikitty = wikitty; + this.toStore = true; + } + /** use for deletion command */ + public CommandSolr(String id) { + this.id = id; + this.toStore = false; + } + } + + static protected class TypeFieldModifer implements Restriction2Solr.FieldModifier { + protected WikittyExtensionStorage extensionStorage; + public TypeFieldModifer(WikittyExtensionStorage extensionStorage) { + this.extensionStorage = extensionStorage; + } + + public String convertToSolr(String fqfieldname) { + String result = fqfieldname; + String[] searchField = fqfieldname.split("\\."); + + if (searchField.length == 2) { + String extName = searchField[0]; + String fieldName = searchField[1]; + + String version = extensionStorage.getLastVersion(extName); + if (version != null) { // not valid extension is version == null + WikittyExtension ext = extensionStorage.restore( + WikittyExtension.computeId(extName, version)); + FieldType type = ext.getFieldType(fieldName.replace(" ", "_")); + if (type != null) { // type can be null if extension version differ + result = WikittySearchEngineSolr.getSolrFieldName( + fqfieldname, type); + } else { + log.debug(String.format( + "Field '%s' could not be found in '%s'", + fqfieldname, extName)); + } + } else { + log.warn("No version for extension " + extName); + } + } + + if (searchField.length == 3) { + String extName = searchField[0]; + String fieldName = searchField[1]; + String fieldType = searchField[2]; + + if(Criteria.ALL_EXTENSIONS.equals(extName)) { + TYPE type = FieldType.TYPE.valueOf(fieldType); + String solrFieldName = SOLR_ALL_EXTENSIONS + "." + fieldName; + result = WikittySearchEngineSolr.getSolrFieldName(solrFieldName, type); + } else { + log.warn("All extension not found " + extName); + } + } + + return result; + } + + public String convertToField(String solrName) { + String fieldname = solrName.replaceAll("(_b$)|(_dt$)|(_t$)|(_l$)", ""); + return fieldname; + } + + } + + protected static class ReindexChildTreeNode extends HashSet<String> { + public static ReindexChildTreeNode getReindexChildTreeNode(WikittyTransaction transaction) { + ReindexChildTreeNode value = (ReindexChildTreeNode) transaction.getTagValue(ReindexChildTreeNode.class); + if(value == null) { + value = new ReindexChildTreeNode(); + transaction.setTagValue(ReindexChildTreeNode.class, value); + } + return value; + } + } + + /** + * Store parent for each node and search in index if not known parent + */ + protected static class ParentMap extends HashMap<String, String> { + + protected WikittySearchEngineSolr searchEnginSolr; + + public ParentMap(WikittySearchEngineSolr searchEnginSolr) { + this.searchEnginSolr = searchEnginSolr; + } + + @Override + public String get(Object key) { + String id = String.valueOf(key); + String parent = super.get(id); + + // If not found in map, search in index + if(parent == null) { + SolrDocument doc = searchEnginSolr.findById(id); + if(doc == null) { + // is root + return null; + } + parent = (String) doc.getFieldValue(TreeNode.FQ_FIELD_PARENT); + put(id, parent); + } + return parent; + } + + /** + * Add parent map in transaction if is not exists and return it + */ + public static ParentMap getParentMap( + WikittySearchEngineSolr searchEnginSolr, + WikittyTransaction transaction) { + ParentMap value = (ParentMap) transaction.getTagValue(ParentMap.class); + if(value == null) { + value = new ParentMap(searchEnginSolr); + transaction.setTagValue(ParentMap.class, value); + } + return value; + } + } + + /** solr server */ + protected SolrServer solrServer; + /** Criteria transformer to solr */ + protected Restriction2Solr restriction2Solr; + /** Field modifier use to transform to solr format */ + protected TypeFieldModifer fieldModifier; + + public WikittySearchEngineSolr(WikittyExtensionStorage extensionStorage) { + super(); + try { + CoreContainer.Initializer initializer = new CoreContainer.Initializer(); + CoreContainer coreContainer = initializer.initialize(); + solrServer = new EmbeddedSolrServer(coreContainer, ""); + + fieldModifier = new TypeFieldModifer(extensionStorage); + restriction2Solr = new Restriction2Solr(fieldModifier); + + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + public void clear() { + try { + solrServer.deleteByQuery("*:*"); + solrServer.commit(true, true); + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + public void changeDataDir(String newDataDir, String oldDataDir) { + try { + if(oldDataDir != null) { + File newFile = new File(newDataDir); + File oldFile = new File(oldDataDir); + FileUtil.copyRecursively(oldFile, newFile); + } + CoreContainer.Initializer initializer = new CoreContainer.Initializer(); + initializer.setSolrConfigFilename(newDataDir); + CoreContainer coreContainer = initializer.initialize(); + solrServer = new EmbeddedSolrServer(coreContainer, ""); + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + public List<Command> prepare(WikittyTransaction transaction, + Collection<Wikitty> wikitties) { + List<Command> result = new ArrayList<Command>(wikitties.size()); + ReindexChildTreeNode reindexChildTreeNode = ReindexChildTreeNode.getReindexChildTreeNode(transaction); + + for (Wikitty w : wikitties) { + + if(w.hasExtension(TreeNode.EXT_TREENODE)) { + Set<String> children = w.getFieldAsSet(TreeNode.EXT_TREENODE, TreeNode.FIELD_CHILDREN, String.class); + if(children != null) { + reindexChildTreeNode.addAll(children); + } + + // Search deleted children + String treeNodeId = w.getId(); + SolrDocument treeNodeDoc = findById(treeNodeId); + if(treeNodeDoc != null) { + Collection oldChildren = treeNodeDoc. + getFieldValues(TreeNode.FQ_FIELD_CHILDREN + "_t"); + if(oldChildren != null) { + reindexChildTreeNode.addAll(oldChildren); + } + } + + } + + result.add(new CommandSolr(w)); + } + return result; + } + + public List<Command> delete(WikittyTransaction transaction, + List<String> idList) throws WikittyException { + List<Command> result = new ArrayList<Command>(idList.size()); + ReindexChildTreeNode reindexChildTreeNode = ReindexChildTreeNode.getReindexChildTreeNode(transaction); + + try { + for (String id : idList) { + SolrQuery query = new SolrQuery(SOLR_QUERY_PARSER + TREENODE_PREFIX + id + ":*"); + QueryResponse response = solrServer.query(query); + SolrDocumentList updateDocs = response.getResults(); + + for (Iterator<SolrDocument> iterator = updateDocs.iterator(); + iterator.hasNext();) { + SolrDocument solrDocument = iterator.next(); + String childId = (String) solrDocument.getFieldValue(TREENODE_CHILD); + reindexChildTreeNode.add(childId); + } + + result.add(new CommandSolr(id)); + } + } catch (Exception eee) { + throw new WikittyException(eee); + } + + return result; + } + + public UpdateResponse commit(WikittyTransaction transaction, + List<Command> wikittyIndexationCommandList) { + try { + + for (Command c : wikittyIndexationCommandList) { + CommandSolr cs = (CommandSolr) c; + if (cs.toStore) { + SolrInputDocument doc = createIndexDocument(cs.wikitty); + solrServer.add(doc); + } else { + // Delete all reference on tree + solrServer.deleteById(TREENODE_PREFIX + cs.id); + + solrServer.deleteById(cs.id); + } + } + solrServer.commit(); + + // Reindex child in tree node + ParentMap parentMap = ParentMap.getParentMap(this, transaction); + ReindexChildTreeNode reindexChildTreeNode = ReindexChildTreeNode.getReindexChildTreeNode(transaction); + for (String childId : reindexChildTreeNode) { + SolrInputDocument doc = createTreeNodeDocument(parentMap, childId); + solrServer.add(doc); + } + solrServer.commit(); + + // no specific result needed + UpdateResponse result = new UpdateResponse(); + return result; + } catch (Exception eee) { + throw new WikittyException(eee); + } + } + + public PagedResult<String> findAllByCriteria(Criteria criteria) { + try { + + // Create query with restriction + String queryString = restriction2Solr.toSolr(criteria.getRestriction(), solrServer); + SolrQuery query = new SolrQuery(SOLR_QUERY_PARSER + queryString); + + // Add pagged + int firstIndex = criteria.getFirstIndex(); + int endIndex = criteria.getEndIndex(); + + query.setStart(firstIndex); + int nbRows; + if (endIndex == -1) { + // WARNING It is necessary to substract 'start' otherwise, there is a capacity overlow in solR + nbRows = Integer.MAX_VALUE - firstIndex; + } else { + nbRows = endIndex - firstIndex + 1; + } + query.setRows(nbRows); + + // Add sorting + List<String> sortAscending = criteria.getSortAscending(); + if(sortAscending != null) { + for (String sort : sortAscending) { + String tranform = fieldModifier.convertToSolr(sort); + query.setSortField(tranform, SolrQuery.ORDER.asc); + } + } + + List<String> sortDescending = criteria.getSortDescending(); + if(sortDescending != null) { + for (String sort : sortDescending) { + String tranform = fieldModifier.convertToSolr(sort); + query.setSortField(tranform, SolrQuery.ORDER.desc); + } + } + + // Add faceting + List<String> facetField = criteria.getFacetField(); + log.debug("facetField : " + facetField); + List<Criteria> facetCriteria = criteria.getFacetCriteria(); + + // use to map query string to criteria facet name + Map<String, String> facetQueryToName = new HashMap<String, String>(); + + if ((facetField != null && !facetField.isEmpty()) + || (facetCriteria != null && !facetCriteria.isEmpty())) { + query.setFacet(true); + query.setFacetMinCount(1); + // query.setFacetLimit(8); // no limit actualy + + // field facetisation + if (facetField != null) { + for (String fqfieldName : facetField) { + String tranform = fieldModifier.convertToSolr(fqfieldName); + query.addFacetField(tranform); + } + } + + // query facetisation + if (facetCriteria != null) { + for (Criteria facet : facetCriteria) { + String queryFacet = + restriction2Solr.toSolr(facet.getRestriction()); + facetQueryToName.put(queryFacet, facet.getName()); + query.addFacetQuery(queryFacet); + } + } + } + + QueryResponse resp = solrServer.query(query); + SolrDocumentList solrResults = resp.getResults(); + + Map<String, List<FacetTopic>> facets = new HashMap<String, List<FacetTopic>>(); + if (facetField != null && !facetField.isEmpty()) { + for (FacetField facet : resp.getFacetFields()) { + String facetName = fieldModifier.convertToField(facet.getName()); + List<FacetTopic> topics = new ArrayList<FacetTopic>(); + if (facet.getValues() != null) { + for (FacetField.Count value : facet.getValues()) { + String topicName = value.getName(); + if(!topicName.endsWith(TREENODE_EMPTY)) { + int topicCount = (int) value.getCount(); + FacetTopic topic = new FacetTopic(facetName, topicName, topicCount); + topics.add(topic); + } + } + } + facets.put(facetName, topics); + } + } + if (facetCriteria != null && !facetCriteria.isEmpty()) { + for (Map.Entry<String, Integer> facet : resp.getFacetQuery().entrySet()) { + String facetName = facet.getKey(); + // don't use contains because, map can have key with null value + if (null != facetQueryToName.get(facetName)) { + facetName = facetQueryToName.get(facetName); + } + Integer count = facet.getValue(); + List<FacetTopic> topics = new ArrayList<FacetTopic>(); + FacetTopic topic = new FacetTopic(facetName, facetName, count); + topics.add(topic); + facets.put(facetName, topics); + } + } + + List<String> ids = new ArrayList<String>(solrResults.size()); + for (SolrDocument doc : solrResults) { + String id = (String) doc.getFieldValue(SOLR_ID); + ids.add(id); + } + + int numFound = (int)resp.getResults().getNumFound(); + PagedResult<String> result = new PagedResult<String>( + firstIndex, numFound, queryString, facets, ids); + + return result; + } catch (SolrServerException e) { + throw new WikittyException(e); + } + } + + public Map<String, Integer> findAllChildren(Wikitty w) { + String wikittyId = w.getId(); + + String parent = w.getFieldAsWikitty(TreeNode.EXT_TREENODE, TreeNode.FIELD_PARENT); + if(parent == null) { + parent = TREENODE_ROOT; + } else { + parent = TREENODE_PREFIX + parent; + } + + // Find count with facet, if the node not contain recurcively content, + // the node not found with facet + Criteria criteria = Search.query().eq(parent, wikittyId).criteria() + .setFirstIndex(0).setEndIndex(0) + .addFacetField(TREENODE_PREFIX + wikittyId); + PagedResult<String> search = findAllByCriteria(criteria); + + Map<String, Integer> counts = new HashMap<String, Integer>(); + List<FacetTopic> topics = search.getTopic(TREENODE_PREFIX + wikittyId); + if(topics != null) { + for (FacetTopic topic : topics) { + String topicName = topic.getTopicName(); + int topicCount = topic.getCount(); + counts.put(topicName, topicCount); + } + } + + log.debug("Facet result " + counts); + + // Find all children, add the other node not found with facet + criteria = Search.query().eq(TreeNode.FQ_FIELD_PARENT, wikittyId).criteria() + .setFirstIndex(0).setEndIndex(Criteria.ALL_ELEMENTS); + search = findAllByCriteria(criteria); + + List<String> children = search.getAll(); + for (String child : children) { + if(!counts.containsKey(child)) { + counts.put(child, 0); + } + } + + return counts; + } + + /** + * Create all index document to used to modify indexation. + * this method don't modify index + * @param w all wikitties object to index + * @return list of SolrInputDocument used to modify index + */ + protected SolrInputDocument createIndexDocument(Wikitty w) { + log.debug("index wikitty " + w.getId()); + + SolrInputDocument doc = new SolrInputDocument(); + String id = w.getId(); + doc.addField(SOLR_ID,id); + + for (String name : w.getExtensionNames()) { + doc.addField(SOLR_EXTENSIONS, name); + } + + for (String fqfieldName : w.fieldNames()) { + FieldType type = w.getFieldType(fqfieldName); + // do not index wikitty field reference +// if (type.getType() == FieldType.TYPE.WIKITTY) { +// continue; +// } + String solrFqFieldName = getSolrFieldName(fqfieldName, type ); + String[] extAndName = solrFqFieldName.split("\\."); + String solrFieldName = SOLR_ALL_EXTENSIONS + "." + extAndName[1]; + if (type.isCollection()) { + Collection collection = (Collection) w.getFqField(fqfieldName); + if (collection != null) { + for (Object objectValue : collection) { + if (objectValue != null) { + // String value = WikittyUtil.toString(type, objectValue); + Object value = objectValue; + doc.addField(solrFqFieldName, value); + doc.addField(solrFieldName, value); + } + } + } + } else { + Object objectValue = w.getFqField(fqfieldName); + if (objectValue != null) { + // String value = WikittyUtil.toString(type, objectValue); + Object value = objectValue; + log.debug("index field " + solrFqFieldName + " with value '" + value + "'"); + doc.addField(solrFqFieldName, value); + doc.addField(solrFieldName, value); + } + } + } + return doc; + } + + /** + * Create a doc between nodes and child + */ + public SolrInputDocument createTreeNodeDocument(ParentMap parentMap, String childId) throws IOException, SolrServerException { + SolrInputDocument doc = new SolrInputDocument(); + doc.setField(SOLR_ID, TREENODE_PREFIX + childId); + doc.setField(TREENODE_CHILD, childId); + + // Find all node contain child + SolrQuery query = new SolrQuery(SOLR_QUERY_PARSER + TreeNode.FQ_FIELD_CHILDREN + "_t:" + childId); + QueryResponse response = solrServer.query(query); + SolrDocumentList updateDocs = response.getResults(); + + List<String> paths = new ArrayList<String>(); + for (Iterator<SolrDocument> iterator = updateDocs.iterator(); + iterator.hasNext();) { + SolrDocument solrDocument = iterator.next(); + + String treeNodeId = (String) solrDocument.getFieldValue(SOLR_ID); + doc.addField(TREENODE_PREFIX + treeNodeId, TREENODE_EMPTY); + + // Add path + String childParent = treeNodeId; + String parent = parentMap.get(childParent); + while (parent != null) { + if(!paths.contains(parent)) { + doc.addField(TREENODE_PREFIX + parent, childParent); + paths.add(parent); + } + + childParent = parent; + parent = parentMap.get(childParent); + } + doc.addField(TREENODE_ROOT, childParent); + } + + return doc; + } + + /** + * Update all document depend a deleted node in tree + */ + public void updateTreeNodeDocument(Map<String, SolrInputDocument> documents, String nodeId) throws SolrServerException { + SolrQuery query = new SolrQuery(SOLR_QUERY_PARSER + TREENODE_PREFIX + nodeId + ":*"); + QueryResponse response = solrServer.query(query); + SolrDocumentList updateDocs = response.getResults(); + + for (Iterator<SolrDocument> iterator = updateDocs.iterator(); iterator.hasNext();) { + SolrDocument solrDocument = iterator.next(); + + String documentId = (String) solrDocument.getFieldValue(SOLR_ID); + SolrInputDocument alreadyDone = documents.get(documentId); + + if (alreadyDone == null) { + SolrInputDocument doc = updateTreeNodeDocument(solrDocument, nodeId); + documents.put(documentId, doc); + } else { + // Copy other field after node + String parent = (String) alreadyDone.getFieldValue(TREENODE_PREFIX + nodeId); + if (parent != null) { + // Recreate doc a sub node is deleted + SolrInputDocument doc = updateTreeNodeDocument(solrDocument, nodeId); + documents.put(documentId, doc); + } + } + } + } + + /** + * Re-create a new document without node deleted, from age document + */ + public SolrInputDocument updateTreeNodeDocument(SolrDocument solrDocument, String nodeId) { + String documentId = (String) solrDocument.getFieldValue(SOLR_ID); + + SolrInputDocument doc = new SolrInputDocument(); + doc.setField(SOLR_ID, documentId); + doc.setField(TREENODE_CHILD, solrDocument.getFieldValue(TREENODE_CHILD)); + + // Copy other field after node + String parent = (String) solrDocument.getFieldValue(TREENODE_PREFIX + nodeId); + if (parent != null) { + String childParent = (String) solrDocument.getFieldValue(parent); + while (childParent != null) { + doc.setField(parent, childParent); + parent = TREENODE_PREFIX + childParent; + childParent = (String) solrDocument.getFieldValue(parent); + } + } + + return doc; + } + + /** + * Find solr document by id + */ + protected SolrDocument findById(String id) { + SolrQuery query = new SolrQuery("id:" + id); + QueryResponse response; + try { + response = solrServer.query(query); + } catch (SolrServerException eee) { + throw new WikittyException(eee); + } + + SolrDocumentList results = response.getResults(); + long numFound = results.getNumFound(); + if(numFound == 1) { + return results.get(0); + } + + return null; + } + + static public String getSolrFieldName(String fqfieldName, FieldType fieldType) { + TYPE type = fieldType.getType(); + String result = getSolrFieldName(fqfieldName, type); + return result; + } + + public static String getSolrFieldName(String fqfieldName, TYPE type) { + switch (type) { + case BOOLEAN: + return fqfieldName + "_b"; + case DATE: + return fqfieldName + "_dt"; + case STRING: + return fqfieldName + "_t"; + case NUMERIC: + return fqfieldName + "_d"; + default: + return fqfieldName; + } + } +} Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/schema.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/schema.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/schema.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,325 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- + This is the Solr schema file. This file should be named "schema.xml" and + should be in the conf directory under the solr home + (i.e. ./solr/conf/schema.xml by default) + or located where the classloader for the Solr webapp can find it. + + This example schema is the recommended starting point for users. + It should be kept correct and concise, usable out-of-the-box. + + For more information, on how to customize this file, please see + http://wiki.apache.org/solr/SchemaXml +--> + +<schema name="wikitty" version="1.1"> + <!-- attribute "name" is the name of this schema and is only used for display purposes. + Applications should change this to reflect the nature of the search collection. + version="1.1" is Solr's version number for the schema syntax and semantics. It should + not normally be changed by applications. + 1.0: multiValued attribute did not exist, all fields are multiValued by nature + 1.1: multiValued attribute introduced, false by default --> + + <types> + <!-- field type definitions. The "name" attribute is + just a label to be used by field definitions. The "class" + attribute and any other attributes determine the real + behavior of the fieldType. + Class names starting with "solr" refer to java classes in the + org.apache.solr.analysis package. + --> + + <!-- The StrField type is not analyzed, but indexed/stored verbatim. + - StrField and TextField support an optional compressThreshold which + limits compression (if enabled in the derived fields) to values which + exceed a certain size (in characters). + --> + <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/> + + <!-- boolean type: "true" or "false" --> + <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/> + + <!-- The optional sortMissingLast and sortMissingFirst attributes are + currently supported on types that are sorted internally as strings. + - If sortMissingLast="true", then a sort on this field will cause documents + without the field to come after documents with the field, + regardless of the requested sort order (asc or desc). + - If sortMissingFirst="true", then a sort on this field will cause documents + without the field to come before documents with the field, + regardless of the requested sort order. + - If sortMissingLast="false" and sortMissingFirst="false" (the default), + then default lucene sorting will be used which places docs without the + field first in an ascending sort and last in a descending sort. + --> + + + <!-- numeric field types that store and index the text + value verbatim (and hence don't support range queries, since the + lexicographic ordering isn't equal to the numeric ordering) --> + <fieldType name="integer" class="solr.IntField" omitNorms="true"/> + <fieldType name="long" class="solr.LongField" omitNorms="true"/> + <fieldType name="float" class="solr.FloatField" omitNorms="true"/> + <fieldType name="double" class="solr.DoubleField" omitNorms="true"/> + + + <!-- Numeric field types that manipulate the value into + a string value that isn't human-readable in its internal form, + but with a lexicographic ordering the same as the numeric ordering, + so that range queries work correctly. --> + <fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/> + <fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/> + <fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/> + <fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/> + + + <!-- The format for this date field is of the form 1995-12-31T23:59:59Z, and + is a more restricted form of the canonical representation of dateTime + http://www.w3.org/TR/xmlschema-2/#dateTime + The trailing "Z" designates UTC time and is mandatory. + Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z + All other components are mandatory. + + Expressions can also be used to denote calculations that should be + performed relative to "NOW" to determine the value, ie... + + NOW/HOUR + ... Round to the start of the current hour + NOW-1DAY + ... Exactly 1 day prior to now + NOW/DAY+6MONTHS+3DAYS + ... 6 months and 3 days in the future from the start of + the current day + + Consult the DateField javadocs for more information. + --> + <fieldType name="date" class="solr.DateField" sortMissingLast="true" omitNorms="true"/> + + + <!-- The "RandomSortField" is not used to store or search any + data. You can declare fields of this type it in your schema + to generate psuedo-random orderings of your docs for sorting + purposes. The ordering is generated based on the field name + and the version of the index, As long as the index version + remains unchanged, and the same field name is reused, + the ordering of the docs will be consistent. + If you want differend psuedo-random orderings of documents, + for the same version of the index, use a dynamicField and + change the name + --> + <fieldType name="random" class="solr.RandomSortField" indexed="true" /> + + <!-- solr.TextField allows the specification of custom text analyzers + specified as a tokenizer and a list of token filters. Different + analyzers may be specified for indexing and querying. + + The optional positionIncrementGap puts space between multiple fields of + this type on the same document, with the purpose of preventing false phrase + matching across fields. + + For more info on customizing your analyzer chain, please see + http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters + --> + + <!-- One can also specify an existing Analyzer class that has a + default constructor via the class attribute on the analyzer element + <fieldType name="text_greek" class="solr.TextField"> + <analyzer class="org.apache.lucene.analysis.el.GreekAnalyzer"/> + </fieldType> + --> + + <!-- A text field that only splits on whitespace for exact matching of words --> + <fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100"> + <analyzer> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + </analyzer> + </fieldType> + + <!-- A text field that uses WordDelimiterFilter to enable splitting and matching of + words on case-change, alpha numeric boundaries, and non-alphanumeric chars, + so that a query of "wifi" or "wi fi" could match a document containing "Wi-Fi". + Synonyms and stopwords are customized by external files, and stemming is enabled. + Duplicate tokens at the same position (which may result from Stemmed Synonyms or + WordDelim parts) are removed. + --> + <fieldType name="text" class="solr.TextField" positionIncrementGap="100"> + <analyzer type="index"> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + <!-- in this example, we will only use synonyms at query time + <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/> + --> + <!-- Case insensitive stop word removal. + enablePositionIncrements=true ensures that a 'gap' is left to + allow for accurate phrase queries. + --> + <filter class="solr.StopFilterFactory" + ignoreCase="true" + words="stopwords.txt" + enablePositionIncrements="true" + /> + <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + <analyzer type="query"> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> + <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> + <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + </fieldType> + + <fieldType name="text_fr" class="solr.TextField" positionIncrementGap="100"> + <analyzer> + <tokenizer class="solr.StandardTokenizerFactory"/> + <filter class="solr.ISOLatin1AccentFilterFactory"/> + <filter class="solr.StandardFilterFactory"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/> + <filter class="solr.SnowballPorterFilterFactory" language="French"/> + </analyzer> + </fieldType> + + <fieldType name="text_core" class="solr.TextField" positionIncrementGap="100"> + <analyzer> + <tokenizer class="solr.WhitespaceTokenizerFactory" /> + <filter class="solr.LowerCaseFilterFactory" /> + <!-- filter class="solr.WordDelimiterFilterFactory" + generateWordParts="1" generateNumberParts="1" + catenateWords="1" catenateNumbers="1" + catenateAll="0" splitOnCaseChange="1" / --> + </analyzer> + </fieldType> + + + <!-- Less flexible matching, but less false matches. Probably not ideal for product names, + but may be good for SKUs. Can insert dashes in the wrong place and still match. --> + <fieldType name="textTight" class="solr.TextField" positionIncrementGap="100" > + <analyzer> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> + <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/> + <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> + <filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + </fieldType> + + <!-- + Setup simple analysis for spell checking + --> + <fieldType name="textSpell" class="solr.TextField" positionIncrementGap="100" > + <analyzer> + <tokenizer class="solr.StandardTokenizerFactory"/> + <filter class="solr.LowerCaseFilterFactory"/> + <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> + </analyzer> + </fieldType> + + <!-- This is an example of using the KeywordTokenizer along + With various TokenFilterFactories to produce a sortable field + that does not include some properties of the source text + --> + <fieldType name="alphaOnlySort" class="solr.TextField" sortMissingLast="true" omitNorms="true"> + <analyzer> + <!-- KeywordTokenizer does no actual tokenizing, so the entire + input string is preserved as a single token + --> + <tokenizer class="solr.KeywordTokenizerFactory"/> + <!-- The LowerCase TokenFilter does what you expect, which can be + when you want your sorting to be case insensitive + --> + <filter class="solr.LowerCaseFilterFactory" /> + <!-- The TrimFilter removes any leading or trailing whitespace --> + <filter class="solr.TrimFilterFactory" /> + <!-- The PatternReplaceFilter gives you the flexibility to use + Java Regular expression to replace any sequence of characters + matching a pattern with an arbitrary replacement string, + which may include back refrences to portions of the orriginal + string matched by the pattern. + + See the Java Regular Expression documentation for more + infomation on pattern and replacement string syntax. + + http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/package-summary.html + --> + <filter class="solr.PatternReplaceFilterFactory" + pattern="([^a-z])" replacement="" replace="all" + /> + </analyzer> + </fieldType> + + <!-- since fields of this type are by default not stored or indexed, any data added to + them will be ignored outright + --> + <fieldtype name="ignored" stored="false" indexed="false" class="solr.StrField" /> + + </types> + + + <fields> + <field name="id" type="text_fr" indexed="true" stored="true" required="true" /> + <field name="extensions" type="text_fr" indexed="true" stored="false" multiValued="true"/> + + <!-- catchall field, containing all other searchable text fields (implemented + via copyField further on in this schema --> + <field name="text" type="text_fr" indexed="true" stored="false" multiValued="true"/> + <copyField source="*_i" dest="text"/> + <copyField source="*_s" dest="text"/> + <copyField source="*_l" dest="text"/> + <copyField source="*_t" dest="text"/> + <copyField source="*_b" dest="text"/> + <copyField source="*_f" dest="text"/> + <copyField source="*_d" dest="text"/> + <copyField source="*_dt" dest="text"/> + + <dynamicField name="*_i" type="sint" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_s" type="text_fr" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_l" type="slong" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_t" type="text_fr" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_b" type="boolean" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_f" type="sfloat" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_d" type="sdouble" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_dt" type="date" indexed="true" stored="true" multiValued="true"/> + + <!-- all wikitty field --> + <dynamicField name="*" type="text_fr" indexed="true" stored="true" multiValued="true"/> + + <!-- copy fields for optimisation --> + <dynamicField name="_*" type="text_fr" indexed="true" stored="true" multiValued="true"/> + + </fields> + + <!-- Field to use to determine and enforce document uniqueness. + Unless this field is marked with required="false", it will be a required field + --> + <uniqueKey>id</uniqueKey> + + <!-- field for the QueryParser to use when an explicit fieldname is absent --> + <defaultSearchField>text</defaultSearchField> + + <!-- SolrQueryParser configuration: defaultOperator="AND|OR" --> + <solrQueryParser defaultOperator="AND"/> + +</schema> \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/solrconfig.xml =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/solrconfig.xml (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/solrconfig.xml 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,700 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<config> + <!-- Set this to 'false' if you want solr to continue working after it has + encountered an severe configuration error. In a production environment, + you may want solr to keep working even if one handler is mis-configured. + + You may also set this to false using by setting the system property: + -Dsolr.abortOnConfigurationError=false + --> + <abortOnConfigurationError>${solr.abortOnConfigurationError:true}</abortOnConfigurationError> + + <!-- Used to specify an alternate directory to hold all index data + other than the default ./data under the Solr home. + If replication is in use, this should match the replication configuration. --> + <dataDir>${solr.data.dir:./solr/data}</dataDir> + + + <indexDefaults> + <!-- Values here affect all index writers and act as a default unless overridden. --> + <useCompoundFile>false</useCompoundFile> + + <mergeFactor>10</mergeFactor> + <!-- + If both ramBufferSizeMB and maxBufferedDocs is set, then Lucene will flush based on whichever limit is hit first. + + --> + <!--<maxBufferedDocs>1000</maxBufferedDocs>--> + <!-- Tell Lucene when to flush documents to disk. + Giving Lucene more memory for indexing means faster indexing at the cost of more RAM + + If both ramBufferSizeMB and maxBufferedDocs is set, then Lucene will flush based on whichever limit is hit first. + + --> + <ramBufferSizeMB>32</ramBufferSizeMB> + <maxMergeDocs>2147483647</maxMergeDocs> + <maxFieldLength>10000</maxFieldLength> + <writeLockTimeout>1000</writeLockTimeout> + <commitLockTimeout>10000</commitLockTimeout> + + <!-- + Expert: Turn on Lucene's auto commit capability. + This causes intermediate segment flushes to write a new lucene + index descriptor, enabling it to be opened by an external + IndexReader. + NOTE: Despite the name, this value does not have any relation to Solr's autoCommit functionality + --> + <!--<luceneAutoCommit>false</luceneAutoCommit>--> + <!-- + Expert: + The Merge Policy in Lucene controls how merging is handled by Lucene. The default in 2.3 is the LogByteSizeMergePolicy, previous + versions used LogDocMergePolicy. + + LogByteSizeMergePolicy chooses segments to merge based on their size. The Lucene 2.2 default, LogDocMergePolicy chose when + to merge based on number of documents + + Other implementations of MergePolicy must have a no-argument constructor + --> + <!--<mergePolicy>org.apache.lucene.index.LogByteSizeMergePolicy</mergePolicy>--> + + <!-- + Expert: + The Merge Scheduler in Lucene controls how merges are performed. The ConcurrentMergeScheduler (Lucene 2.3 default) + can perform merges in the background using separate threads. The SerialMergeScheduler (Lucene 2.2 default) does not. + --> + <!--<mergeScheduler>org.apache.lucene.index.ConcurrentMergeScheduler</mergeScheduler>--> + + <!-- + This option specifies which Lucene LockFactory implementation to use. + + single = SingleInstanceLockFactory - suggested for a read-only index + or when there is no possibility of another process trying + to modify the index. + native = NativeFSLockFactory + simple = SimpleFSLockFactory + + (For backwards compatibility with Solr 1.2, 'simple' is the default + if not specified.) + --> + <lockType>single</lockType> + </indexDefaults> + + <mainIndex> + <!-- options specific to the main on-disk lucene index --> + <useCompoundFile>false</useCompoundFile> + <ramBufferSizeMB>32</ramBufferSizeMB> + <mergeFactor>10</mergeFactor> + <!-- Deprecated --> + <!--<maxBufferedDocs>1000</maxBufferedDocs>--> + <maxMergeDocs>2147483647</maxMergeDocs> + <maxFieldLength>10000</maxFieldLength> + + <!-- If true, unlock any held write or commit locks on startup. + This defeats the locking mechanism that allows multiple + processes to safely access a lucene index, and should be + used with care. + This is not needed if lock type is 'none' or 'single' + --> + <unlockOnStartup>false</unlockOnStartup> + </mainIndex> + + <!-- Enables JMX if and only if an existing MBeanServer is found, use + this if you want to configure JMX through JVM parameters. Remove + this to disable exposing Solr configuration and statistics to JMX. + + If you want to connect to a particular server, specify the agentId + e.g. <jmx agentId="myAgent" /> + + If you want to start a new MBeanServer, specify the serviceUrl + e.g <jmx serviceurl="service:jmx:rmi:///jndi/rmi://localhost:9999/solr" /> + + For more details see http://wiki.apache.org/solr/SolrJmx + --> + <jmx /> + + <!-- the default high-performance update handler --> + <updateHandler class="solr.DirectUpdateHandler2"> + + <!-- A prefix of "solr." for class names is an alias that + causes solr to search appropriate packages, including + org.apache.solr.(search|update|request|core|analysis) + --> + + <!-- Perform a <commit/> automatically under certain conditions: + maxDocs - number of updates since last commit is greater than this + maxTime - oldest uncommited update (in ms) is this long ago + <autoCommit> + <maxDocs>10000</maxDocs> + <maxTime>1000</maxTime> + </autoCommit> + --> + + <!-- The RunExecutableListener executes an external command. + exe - the name of the executable to run + dir - dir to use as the current working directory. default="." + wait - the calling thread waits until the executable returns. default="true" + args - the arguments to pass to the program. default=nothing + env - environment variables to set. default=nothing + --> + <!-- A postCommit event is fired after every commit or optimize command + <listener event="postCommit" class="solr.RunExecutableListener"> + <str name="exe">solr/bin/snapshooter</str> + <str name="dir">.</str> + <bool name="wait">true</bool> + <arr name="args"> <str>arg1</str> <str>arg2</str> </arr> + <arr name="env"> <str>MYVAR=val1</str> </arr> + </listener> + --> + <!-- A postOptimize event is fired only after every optimize command, useful + in conjunction with index distribution to only distribute optimized indicies + <listener event="postOptimize" class="solr.RunExecutableListener"> + <str name="exe">snapshooter</str> + <str name="dir">solr/bin</str> + <bool name="wait">true</bool> + </listener> + --> + + </updateHandler> + + + <query> + <!-- Maximum number of clauses in a boolean query... can affect + range or prefix queries that expand to big boolean + queries. An exception is thrown if exceeded. --> + <maxBooleanClauses>1024</maxBooleanClauses> + + + <!-- Cache used by SolrIndexSearcher for filters (DocSets), + unordered sets of *all* documents that match a query. + When a new searcher is opened, its caches may be prepopulated + or "autowarmed" using data from caches in the old searcher. + autowarmCount is the number of items to prepopulate. For LRUCache, + the autowarmed items will be the most recently accessed items. + Parameters: + class - the SolrCache implementation (currently only LRUCache) + size - the maximum number of entries in the cache + initialSize - the initial capacity (number of entries) of + the cache. (seel java.util.HashMap) + autowarmCount - the number of entries to prepopulate from + and old cache. + --> + <filterCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="128"/> + + <!-- queryResultCache caches results of searches - ordered lists of + document ids (DocList) based on a query, a sort, and the range + of documents requested. --> + <queryResultCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="32"/> + + <!-- documentCache caches Lucene Document objects (the stored fields for each document). + Since Lucene internal document ids are transient, this cache will not be autowarmed. --> + <documentCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="0"/> + + <!-- If true, stored fields that are not requested will be loaded lazily. + + This can result in a significant speed improvement if the usual case is to + not load all stored fields, especially if the skipped fields are large compressed + text fields. + --> + <enableLazyFieldLoading>true</enableLazyFieldLoading> + + <!-- Example of a generic cache. These caches may be accessed by name + through SolrIndexSearcher.getCache(),cacheLookup(), and cacheInsert(). + The purpose is to enable easy caching of user/application level data. + The regenerator argument should be specified as an implementation + of solr.search.CacheRegenerator if autowarming is desired. --> + <!-- + <cache name="myUserCache" + class="solr.LRUCache" + size="4096" + initialSize="1024" + autowarmCount="1024" + regenerator="org.mycompany.mypackage.MyRegenerator" + /> + --> + + <!-- An optimization that attempts to use a filter to satisfy a search. + If the requested sort does not include score, then the filterCache + will be checked for a filter matching the query. If found, the filter + will be used as the source of document ids, and then the sort will be + applied to that. + <useFilterForSortedQuery>true</useFilterForSortedQuery> + --> + + <!-- An optimization for use with the queryResultCache. When a search + is requested, a superset of the requested number of document ids + are collected. For example, if a search for a particular query + requests matching documents 10 through 19, and queryWindowSize is 50, + then documents 0 through 49 will be collected and cached. Any further + requests in that range can be satisfied via the cache. --> + <queryResultWindowSize>50</queryResultWindowSize> + + <!-- Maximum number of documents to cache for any entry in the + queryResultCache. --> + <queryResultMaxDocsCached>200</queryResultMaxDocsCached> + + <!-- This entry enables an int hash representation for filters (DocSets) + when the number of items in the set is less than maxSize. For smaller + sets, this representation is more memory efficient, more efficient to + iterate over, and faster to take intersections. --> + <HashDocSet maxSize="3000" loadFactor="0.75"/> + + <!-- a newSearcher event is fired whenever a new searcher is being prepared + and there is a current searcher handling requests (aka registered). --> + <!-- QuerySenderListener takes an array of NamedList and executes a + local query request for each NamedList in sequence. --> + <listener event="newSearcher" class="solr.QuerySenderListener"> + <arr name="queries"> + <lst> <str name="q">solr</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst> <str name="q">rocks</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst><str name="q">static newSearcher warming query from solrconfig.xml</str></lst> + </arr> + </listener> + + <!-- a firstSearcher event is fired whenever a new searcher is being + prepared but there is no current registered searcher to handle + requests or to gain autowarming data from. --> + <listener event="firstSearcher" class="solr.QuerySenderListener"> + <arr name="queries"> + <lst> <str name="q">fast_warm</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst><str name="q">static firstSearcher warming query from solrconfig.xml</str></lst> + </arr> + </listener> + + <!-- If a search request comes in and there is no current registered searcher, + then immediately register the still warming searcher and use it. If + "false" then all requests will block until the first searcher is done + warming. --> + <useColdSearcher>false</useColdSearcher> + + <!-- Maximum number of searchers that may be warming in the background + concurrently. An error is returned if this limit is exceeded. Recommend + 1-2 for read-only slaves, higher for masters w/o cache warming. --> + <maxWarmingSearchers>2</maxWarmingSearchers> + + </query> + + <!-- + Let the dispatch filter handler /select?qt=XXX + handleSelect=true will use consistent error handling for /select and /update + handleSelect=false will use solr1.1 style error formatting + --> + <requestDispatcher handleSelect="true" > + <!--Make sure your system has some authentication before enabling remote streaming! --> + <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" /> + + <!-- Set HTTP caching related parameters (for proxy caches and clients). + + To get the behaviour of Solr 1.2 (ie: no caching related headers) + use the never304="true" option and do not specify a value for + <cacheControl> + --> + <!-- <httpCaching never304="true"> --> + <httpCaching lastModifiedFrom="openTime" + etagSeed="Solr"> + <!-- lastModFrom="openTime" is the default, the Last-Modified value + (and validation against If-Modified-Since requests) will all be + relative to when the current Searcher was opened. + You can change it to lastModFrom="dirLastMod" if you want the + value to exactly corrispond to when the physical index was last + modified. + + etagSeed="..." is an option you can change to force the ETag + header (and validation against If-None-Match requests) to be + differnet even if the index has not changed (ie: when making + significant changes to your config file) + + lastModifiedFrom and etagSeed are both ignored if you use the + never304="true" option. + --> + <!-- If you include a <cacheControl> directive, it will be used to + generate a Cache-Control header, as well as an Expires header + if the value contains "max-age=" + + By default, no Cache-Control header is generated. + + You can use the <cacheControl> option even if you have set + never304="true" + --> + <!-- <cacheControl>max-age=30, public</cacheControl> --> + </httpCaching> + </requestDispatcher> + + + <!-- requestHandler plugins... incoming queries will be dispatched to the + correct handler based on the path or the qt (query type) param. + Names starting with a '/' are accessed with the a path equal to the + registered name. Names without a leading '/' are accessed with: + http://host/app/select?qt=name + If no qt is defined, the requestHandler that declares default="true" + will be used. + --> + <requestHandler name="standard" class="solr.SearchHandler" default="true"> + <!-- default values for query parameters --> + <lst name="defaults"> + <str name="echoParams">explicit</str> + <!-- + <int name="rows">10</int> + <str name="fl">*</str> + <str name="version">2.1</str> + --> + </lst> + </requestHandler> + + + <!-- DisMaxRequestHandler allows easy searching across multiple fields + for simple user-entered phrases. It's implementation is now + just the standard SearchHandler with a default query type + of "dismax". + see http://wiki.apache.org/solr/DisMaxRequestHandler + --> + <requestHandler name="dismax" class="solr.SearchHandler" > + <lst name="defaults"> + <str name="defType">dismax</str> + <str name="echoParams">explicit</str> + <float name="tie">0.01</float> + <str name="qf"> + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + </str> + <str name="pf"> + text^0.2 features^1.1 name^1.5 manu^1.4 manu_exact^1.9 + </str> + <str name="bf"> + ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3 + </str> + <str name="fl"> + id,name,price,score + </str> + <str name="mm"> + 2<-1 5<-2 6<90% + </str> + <int name="ps">100</int> + <str name="q.alt">*:*</str> + <!-- example highlighter config, enable per-query with hl=true --> + <str name="hl.fl">text features name</str> + <!-- for this field, we want no fragmenting, just highlighting --> + <str name="f.name.hl.fragsize">0</str> + <!-- instructs Solr to return the field itself if no query terms are + found --> + <str name="f.name.hl.alternateField">name</str> + <str name="f.text.hl.fragmenter">regex</str> <!-- defined below --> + </lst> + </requestHandler> + + <!-- Note how you can register the same handler multiple times with + different names (and different init parameters) + --> + <requestHandler name="partitioned" class="solr.SearchHandler" > + <lst name="defaults"> + <str name="defType">dismax</str> + <str name="echoParams">explicit</str> + <str name="qf">text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0</str> + <str name="mm">2<-1 5<-2 6<90%</str> + <!-- This is an example of using Date Math to specify a constantly + moving date range in a config... + --> + <str name="bq">incubationdate_dt:[* TO NOW/DAY-1MONTH]^2.2</str> + </lst> + <!-- In addition to defaults, "appends" params can be specified + to identify values which should be appended to the list of + multi-val params from the query (or the existing "defaults"). + + In this example, the param "fq=instock:true" will be appended to + any query time fq params the user may specify, as a mechanism for + partitioning the index, independent of any user selected filtering + that may also be desired (perhaps as a result of faceted searching). + + NOTE: there is *absolutely* nothing a client can do to prevent these + "appends" values from being used, so don't use this mechanism + unless you are sure you always want it. + --> + <lst name="appends"> + <str name="fq">inStock:true</str> + </lst> + <!-- "invariants" are a way of letting the Solr maintainer lock down + the options available to Solr clients. Any params values + specified here are used regardless of what values may be specified + in either the query, the "defaults", or the "appends" params. + + In this example, the facet.field and facet.query params are fixed, + limiting the facets clients can use. Faceting is not turned on by + default - but if the client does specify facet=true in the request, + these are the only facets they will be able to see counts for; + regardless of what other facet.field or facet.query params they + may specify. + + NOTE: there is *absolutely* nothing a client can do to prevent these + "invariants" values from being used, so don't use this mechanism + unless you are sure you always want it. + --> + <lst name="invariants"> + <str name="facet.field">cat</str> + <str name="facet.field">manu_exact</str> + <str name="facet.query">price:[* TO 500]</str> + <str name="facet.query">price:[500 TO *]</str> + </lst> + </requestHandler> + + + <!-- + Search components are registered to SolrCore and used by Search Handlers + + By default, the following components are avaliable: + + <searchComponent name="query" class="org.apache.solr.handler.component.QueryComponent" /> + <searchComponent name="facet" class="org.apache.solr.handler.component.FacetComponent" /> + <searchComponent name="mlt" class="org.apache.solr.handler.component.MoreLikeThisComponent" /> + <searchComponent name="highlight" class="org.apache.solr.handler.component.HighlightComponent" /> + <searchComponent name="debug" class="org.apache.solr.handler.component.DebugComponent" /> + + Default configuration in a requestHandler would look like: + <arr name="components"> + <str>query</str> + <str>facet</str> + <str>mlt</str> + <str>highlight</str> + <str>debug</str> + </arr> + + If you register a searchComponent to one of the standard names, that will be used instead. + To insert handlers before or after the 'standard' components, use: + + <arr name="first-components"> + <str>myFirstComponentName</str> + </arr> + + <arr name="last-components"> + <str>myLastComponentName</str> + </arr> + --> + + <!-- The spell check component can return a list of alternative spelling + suggestions. --> + <searchComponent name="spellcheck" class="solr.SpellCheckComponent"> + + <str name="queryAnalyzerFieldType">textSpell</str> + + <lst name="spellchecker"> + <str name="name">default</str> + <str name="field">spell</str> + <str name="spellcheckIndexDir">./spellchecker1</str> + + </lst> + <lst name="spellchecker"> + <str name="name">jarowinkler</str> + <str name="field">spell</str> + <!-- Use a different Distance Measure --> + <str name="distanceMeasure">org.apache.lucene.search.spell.JaroWinklerDistance</str> + <str name="spellcheckIndexDir">./spellchecker2</str> + + </lst> + + <lst name="spellchecker"> + <str name="classname">solr.FileBasedSpellChecker</str> + <str name="name">file</str> + <str name="sourceLocation">spellings.txt</str> + <str name="characterEncoding">UTF-8</str> + <str name="spellcheckIndexDir">./spellcheckerFile</str> + </lst> + </searchComponent> + + <!-- a request handler utilizing the spellcheck component --> + <requestHandler name="/spellCheckCompRH" class="solr.SearchHandler"> + <lst name="defaults"> + <!-- omp = Only More Popular --> + <str name="spellcheck.onlyMorePopular">false</str> + <!-- exr = Extended Results --> + <str name="spellcheck.extendedResults">false</str> + <!-- The number of suggestions to return --> + <str name="spellcheck.count">1</str> + </lst> + <arr name="last-components"> + <str>spellcheck</str> + </arr> + </requestHandler> + + <!-- a search component that enables you to configure the top results for + a given query regardless of the normal lucene scoring.--> + +<!-- poussin 20090902 remove elevate this file is empty, what need ? + <searchComponent name="elevator" class="solr.QueryElevationComponent" > + <str name="queryFieldType">string</str> + <str name="config-file">elevate.xml</str> + </searchComponent> + --> + <!-- a request handler utilizing the elevator component --> +<!-- + <requestHandler name="/elevate" class="solr.SearchHandler" startup="lazy"> + <lst name="defaults"> + <str name="echoParams">explicit</str> + </lst> + <arr name="last-components"> + <str>elevator</str> + </arr> + </requestHandler> + --> + + <!-- Update request handler. + + Note: Since solr1.1 requestHandlers requires a valid content type header if posted in + the body. For example, curl now requires: -H 'Content-type:text/xml; charset=utf-8' + The response format differs from solr1.1 formatting and returns a standard error code. + + To enable solr1.1 behavior, remove the /update handler or change its path + --> + <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" /> + + <!-- + Analysis request handler. Since Solr 1.3. Use to returnhow a document is analyzed. Useful + for debugging and as a token server for other types of applications + --> + <requestHandler name="/analysis" class="solr.AnalysisRequestHandler" /> + + + <!-- CSV update handler, loaded on demand --> + <requestHandler name="/update/csv" class="solr.CSVRequestHandler" startup="lazy" /> + + + <!-- + Admin Handlers - This will register all the standard admin RequestHandlers. Adding + this single handler is equivolent to registering: + + <requestHandler name="/admin/luke" class="org.apache.solr.handler.admin.LukeRequestHandler" /> + <requestHandler name="/admin/system" class="org.apache.solr.handler.admin.SystemInfoHandler" /> + <requestHandler name="/admin/plugins" class="org.apache.solr.handler.admin.PluginInfoHandler" /> + <requestHandler name="/admin/threads" class="org.apache.solr.handler.admin.ThreadDumpHandler" /> + <requestHandler name="/admin/properties" class="org.apache.solr.handler.admin.PropertiesRequestHandler" /> + <requestHandler name="/admin/file" class="org.apache.solr.handler.admin.ShowFileRequestHandler" > + + If you wish to hide files under ${solr.home}/conf, explicitly register the ShowFileRequestHandler using: + <requestHandler name="/admin/file" class="org.apache.solr.handler.admin.ShowFileRequestHandler" > + <lst name="invariants"> + <str name="hidden">synonyms.txt</str> + <str name="hidden">anotherfile.txt</str> + </lst> + </requestHandler> + --> + <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" /> + + <!-- ping/healthcheck --> + <requestHandler name="/admin/ping" class="PingRequestHandler"> + <lst name="defaults"> + <str name="qt">standard</str> + <str name="q">solrpingquery</str> + <str name="echoParams">all</str> + </lst> + </requestHandler> + + <!-- Echo the request contents back to the client --> + <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" > + <lst name="defaults"> + <str name="echoParams">explicit</str> <!-- for all params (including the default etc) use: 'all' --> + <str name="echoHandler">true</str> + </lst> + </requestHandler> + + <highlighting> + <!-- Configure the standard fragmenter --> + <!-- This could most likely be commented out in the "default" case --> + <fragmenter name="gap" class="org.apache.solr.highlight.GapFragmenter" default="true"> + <lst name="defaults"> + <int name="hl.fragsize">100</int> + </lst> + </fragmenter> + + <!-- A regular-expression-based fragmenter (f.i., for sentence extraction) --> + <fragmenter name="regex" class="org.apache.solr.highlight.RegexFragmenter"> + <lst name="defaults"> + <!-- slightly smaller fragsizes work better because of slop --> + <int name="hl.fragsize">70</int> + <!-- allow 50% slop on fragment sizes --> + <float name="hl.regex.slop">0.5</float> + <!-- a basic sentence pattern --> + <str name="hl.regex.pattern">[-\w ,/\n\"']{20,200}</str> + </lst> + </fragmenter> + + <!-- Configure the standard formatter --> + <formatter name="html" class="org.apache.solr.highlight.HtmlFormatter" default="true"> + <lst name="defaults"> + <str name="hl.simple.pre"><![CDATA[<em>]]></str> + <str name="hl.simple.post"><![CDATA[</em>]]></str> + </lst> + </formatter> + </highlighting> + + + <!-- queryResponseWriter plugins... query responses will be written using the + writer specified by the 'wt' request parameter matching the name of a registered + writer. + The "default" writer is the default and will be used if 'wt' is not specified + in the request. XMLResponseWriter will be used if nothing is specified here. + The json, python, and ruby writers are also available by default. + + <queryResponseWriter name="xml" class="org.apache.solr.request.XMLResponseWriter" default="true"/> + <queryResponseWriter name="json" class="org.apache.solr.request.JSONResponseWriter"/> + <queryResponseWriter name="python" class="org.apache.solr.request.PythonResponseWriter"/> + <queryResponseWriter name="ruby" class="org.apache.solr.request.RubyResponseWriter"/> + <queryResponseWriter name="php" class="org.apache.solr.request.PHPResponseWriter"/> + <queryResponseWriter name="phps" class="org.apache.solr.request.PHPSerializedResponseWriter"/> + + <queryResponseWriter name="custom" class="com.example.MyResponseWriter"/> + --> + + <!-- XSLT response writer transforms the XML output by any xslt file found + in Solr's conf/xslt directory. Changes to xslt files are checked for + every xsltCacheLifetimeSeconds. + --> + <queryResponseWriter name="xslt" class="org.apache.solr.request.XSLTResponseWriter"> + <int name="xsltCacheLifetimeSeconds">5</int> + </queryResponseWriter> + + + <queryParser name="wikitty" class="org.sharengo.wikitty.solr.WikittyQueryParser"/> + + <!-- example of registering a query parser + <queryParser name="lucene" class="org.apache.solr.search.LuceneQParserPlugin"/> + --> + + <!-- example of registering a custom function parser + <valueSourceParser name="myfunc" class="com.mycompany.MyValueSourceParser" /> + --> + + <!-- config for the admin interface --> + <admin> + <defaultQuery>solr</defaultQuery> + + <!-- configure a healthcheck file for servers behind a loadbalancer + <healthcheck type="file">server-enabled</healthcheck> + --> + </admin> + +</config> \ No newline at end of file Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/stopwords.txt =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/stopwords.txt (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/main/resources/stopwords.txt 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +#Standard english stop words taken from Lucene's StopAnalyzer +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +s +such +t +that +the +their +then +there +these +they +this +to +was +will +with + Added: tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/log4j.properties =================================================================== --- tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/log4j.properties (rev 0) +++ tags/wikengo_core-wikitty-1.0.0-alpha-2/wikengo_core-wikitty-solr-impl/src/test/resources/log4j.properties 2009-11-23 14:44:06 UTC (rev 333) @@ -0,0 +1,9 @@ +# Appender and Layout +log4j.appender.logConsole=org.apache.log4j.ConsoleAppender +log4j.appender.logConsole.layout=org.apache.log4j.PatternLayout +log4j.appender.logConsole.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n + +# Configuration by components +log4j.rootLogger=ERROR, logConsole +log4j.category.org.sharengo.wikitty=DEBUG +log4j.category.org.apache.solr=DEBUG