r357 - in trunk/bow-ui: . src/main/java/org/chorem/bow src/main/java/org/chorem/bow/action src/main/java/org/chorem/bow/action/admin src/main/java/org/chorem/bow/action/opensearch src/main/java/org/chorem/bow/action/preference src/main/java/org/chorem/bow/interceptor src/main/resources src/main/resources/i18n src/main/webapp src/main/webapp/WEB-INF/jsp src/main/xmi
Author: bpoussin Date: 2013-09-19 11:27:16 +0200 (Thu, 19 Sep 2013) New Revision: 357 Url: http://chorem.org/projects/bow/repository/revisions/357 Log: fixes #496: bug when we have ':' (separator mark) in search request - suppression de tres vieux script de migration - modification de la notion de prefix, on peut en mettre autant qu'on souhaite - amelioratin des suggestions Added: trunk/bow-ui/src/main/java/org/chorem/bow/BowMigration11To12.java trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/SuggestionAction.java trunk/bow-ui/src/main/java/org/chorem/bow/interceptor/LaxLoginInterceptor.java trunk/bow-ui/src/main/webapp/META-INF/ trunk/bow-ui/src/main/xmi/bow-model.zargo Modified: trunk/bow-ui/pom.xml trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java trunk/bow-ui/src/main/java/org/chorem/bow/BowSession.java trunk/bow-ui/src/main/java/org/chorem/bow/action/AliasAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/admin/MigrateDataAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchBaseAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchResultAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchSuggestionAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties trunk/bow-ui/src/main/resources/log4j.properties trunk/bow-ui/src/main/resources/struts.xml trunk/bow-ui/src/main/webapp/WEB-INF/jsp/admin.jsp trunk/bow-ui/src/main/webapp/WEB-INF/jsp/permanentXml.jsp trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp trunk/bow-ui/src/main/webapp/WEB-INF/jsp/temporaryXml.jsp trunk/bow-ui/src/main/xmi/README Modified: trunk/bow-ui/pom.xml =================================================================== --- trunk/bow-ui/pom.xml 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/pom.xml 2013-09-19 09:27:16 UTC (rev 357) @@ -174,6 +174,13 @@ <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.3</version> + </dependency> + </dependencies> <build> Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java 2013-09-19 09:27:16 UTC (rev 357) @@ -63,6 +63,30 @@ "search.engine", _("bow.config.search.engine.description"), null, String.class, false, false), + TAG_SEARCH_URL( + "bow.prefix.search.tag", + _("bow.config.sprefix.search.tag.description"), + "home.action?tagLine={searchTerms}", String.class, false, false), + FULLTEXT_SEARCH_URL( + "bow.prefix.search.fulltext", + _("bow.config.bow.prefix.search.fulltext.description"), + "home.action?fullTextLine={searchTerms}", String.class, false, false), + ALIAS_SEARCH_URL( + "bow.prefix.search.alias", + _("bow.config.bow.prefix.search.alias.description"), + "alias.action?alias={searchTerms}", String.class, false, false), + TAG_SUGGESTION_URL( + "bow.prefix.suggestion.tag", + _("bow.config.sprefix.suggestion.tag.description"), + "suggestion-tag.action?q={searchTerms}", String.class, false, false), + FULLTEXT_SUGGESTION_URL( + "bow.prefix.suggestion.fulltext", + _("bow.config.bow.prefix.suggestion.fulltext.description"), + "suggestion-fulltext.action?q={searchTerms}", String.class, false, false), + ALIAS_SUGGESTION_URL( + "bow.prefix.suggestion.alias", + _("bow.config.bow.prefix.suggestion.alias.description"), + "suggestion-alias.action?q={searchTerms}", String.class, false, false), OPEN_SEARCH_DEFAULT_ACTION( "opensearch.default.action", _("bow.config.opensearch.default.action.description"), Added: trunk/bow-ui/src/main/java/org/chorem/bow/BowMigration11To12.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BowMigration11To12.java (rev 0) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BowMigration11To12.java 2013-09-19 09:27:16 UTC (rev 357) @@ -0,0 +1,202 @@ +/* + * #%L + * BOW UI + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.bow; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyProxy; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyAuthorisationHelper; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.search.Criteria; +import org.nuiton.wikitty.search.PagedResult; +import org.nuiton.wikitty.search.Search; +import org.nuiton.wikitty.services.WikittyExtensionMigration; +import org.nuiton.wikitty.services.WikittyExtensionMigrationRename; + +import java.util.List; +import org.apache.commons.lang3.StringUtils; + +/** + * Migre les données depuis la version 0.6 vers la version 1.1. + * On suppose que les données sont convenablement indexee. + * <p/> + * <li> ajout du champs BowBookmark.authentificationInfo (rien a faire pour la migration) + * <li> suppression de BowBookmark.bowUser + * <li> BowBookmark depend de WikittyAuthorisation + * <p/> + * la valeur de BowBookmark.bowUser est maintenant stockee dans + * WikittyAuthorisation.owner et WikittyAuthorisation.reader + * pour que par defaut seul le owner est les droits de lecture sur l'item + * + * @author poussin + * @version $Revision$ + * <p/> + * Last update: $Date$ + * by : $Author$ + */ +public class BowMigration11To12 extends WikittyExtensionMigrationRename { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static final Log log = LogFactory.getLog(BowMigration11To12.class); + + /** nombre d'objet a charger en 1 fois */ + public static final int MAX = 1000; + + /** Point d'entree de la migration. */ + @Override + public Wikitty migrate(WikittyService service, Wikitty wikitty, + WikittyExtension oldExt, WikittyExtension newExt) { + + // On met juste a jour les données avec le champs supprimer bowUser + String userId = wikitty.getId(); + + if (userId != null) { + String prefixSeparator = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "prefixSeparator"); + + String defaultAction = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "defaultAction"); + String defaultPrefix = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "defaultPrefix"); + + String tagSearchPrefix = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "tagSearchPrefix"); + String fullTextSearchPrefix = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "fullTextSearchPrefix"); + String webSearchPrefix = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "webSearchPrefix"); + String aliasPrefix = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "aliasPrefix"); + + String searchEngineUrlResults = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "searchEngineUrlResults"); + String searchEngineUrlSuggestions = (String) wikitty.getFqField( + BowPreference.EXT_BOWPREFERENCE + WikittyUtil.FQ_FIELD_NAME_SEPARATOR + + "searchEngineUrlSuggestions"); + + BowSearchPrefixImpl pWeb = new BowSearchPrefixImpl(); + pWeb.setBowUser(userId); + pWeb.setPrefix(webSearchPrefix + prefixSeparator); + pWeb.setSearch(searchEngineUrlResults); + pWeb.setSuggestion(searchEngineUrlSuggestions); + + BowSearchPrefixImpl pTag = new BowSearchPrefixImpl(); + pTag.setBowUser(userId); + pTag.setPrefix(tagSearchPrefix + prefixSeparator); + pTag.setSearch("bowTagSearch"); + pTag.setSuggestion("bowTagSuggest"); + + BowSearchPrefixImpl pFullText = new BowSearchPrefixImpl(); + pFullText.setBowUser(userId); + pFullText.setPrefix(fullTextSearchPrefix + prefixSeparator); + pFullText.setSearch("bowFullTextSearch"); + pFullText.setSuggestion("bowFullTextSuggest"); + + BowSearchPrefixImpl pAlias = new BowSearchPrefixImpl(); + pAlias.setBowUser(userId); + pAlias.setPrefix(aliasPrefix + prefixSeparator); + pAlias.setSearch("bowAliasSearch"); + pAlias.setSuggestion("bowAliasSuggest"); + + BowSearchPrefixImpl pDefault = new BowSearchPrefixImpl(); + if (StringUtils.equals(defaultAction, webSearchPrefix)) { + pDefault.getWikitty().replaceWith(pWeb.getWikitty(), true); + } else if (StringUtils.equals(defaultAction, tagSearchPrefix)) { + pDefault.getWikitty().replaceWith(pTag.getWikitty(), true); + } else if (StringUtils.equals(defaultAction, fullTextSearchPrefix)) { + pDefault.getWikitty().replaceWith(pFullText.getWikitty(), true); + } else if (StringUtils.equals(defaultAction, aliasPrefix)) { + pDefault.getWikitty().replaceWith(pAlias.getWikitty(), true); + } + pDefault.setPrefix(""); + + BowSearchPrefixImpl pDefaultPrefix = new BowSearchPrefixImpl(); + if (StringUtils.equals(defaultAction, webSearchPrefix)) { + pDefaultPrefix.getWikitty().replaceWith(pWeb.getWikitty(), true); + } else if (StringUtils.equals(defaultAction, tagSearchPrefix)) { + pDefaultPrefix.getWikitty().replaceWith(pTag.getWikitty(), true); + } else if (StringUtils.equals(defaultAction, fullTextSearchPrefix)) { + pDefaultPrefix.getWikitty().replaceWith(pFullText.getWikitty(), true); + } else if (StringUtils.equals(defaultAction, aliasPrefix)) { + pDefaultPrefix.getWikitty().replaceWith(pAlias.getWikitty(), true); + } + pDefaultPrefix.setPrefix(prefixSeparator); + + + WikittyProxy proxy = new WikittyProxy(service); + proxy.store(pWeb, pTag, pFullText, pAlias, pDefault, pDefaultPrefix); + } + + // on laisse l'implantation par defaut migrer tout ce qu'il faut + // nouvelle dependance, ... + Wikitty result = super.migrate(service, wikitty, oldExt, newExt); + + return result; + } + + public static void migrate(WikittyProxy proxy) { + log.info("Migration 1.1 to 1.2 started"); + // on enregistre la classe qui fera la migration des données + WikittyExtensionMigration.migrationRegistry.put( + BowPreference.EXT_BOWPREFERENCE, new BowMigration11To12()); + + // une simple lecture puis ecrire fera automatiquement la migration + // grace a la classe enregistree pour. + Criteria criteria = + Search.query().exteq(BowPreference.EXT_BOWPREFERENCE).criteria(); + int i = 0; + int count = 0; + PagedResult<Wikitty> wikitties; + do { + criteria.setFirstIndex(i); + criteria.setEndIndex(i += MAX); + wikitties = proxy.findAllByCriteria(criteria); + List<Wikitty> prefs = wikitties.getAll(); + proxy.storeWikitty(prefs); + count += prefs.size(); + } while (wikitties.size() >= MAX); + log.info(String.format("Migration of %s BowBookmark done", count)); + WikittyExtensionMigration.migrationRegistry.remove( + BowPreference.EXT_BOWPREFERENCE); + } + + // only here to simplify test and debug of migration, this permit to migrate + // datas in developpement environnement directly without launch bow web app + public static void main(String... args) { + BowProxy proxy = BowProxy.getInstance(null); + migrate(proxy); + } +} Property changes on: trunk/bow-ui/src/main/java/org/chorem/bow/BowMigration11To12.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BowSession.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BowSession.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BowSession.java 2013-09-19 09:27:16 UTC (rev 357) @@ -32,7 +32,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import org.nuiton.wikitty.WikittyProxy; +import org.nuiton.wikitty.search.Criteria; +import org.nuiton.wikitty.search.PagedResult; +import org.nuiton.wikitty.search.Search; /** * Classe utilisee pour stocker les objets utils en session utilisateur @@ -101,6 +107,66 @@ return user; } + public List<BowSearchPrefix> getSearchPrefix() { + BowUser user = getUser(); + + Criteria criteria = Search.query() + .exteq(BowSearchPrefix.EXT_BOWSEARCHPREFIX) + .eq(BowSearchPrefix.FQ_FIELD_BOWSEARCHPREFIX_BOWUSER, user.getWikittyId()).criteria() + .setSortAscending(BowSearchPrefix.FQ_FIELD_BOWSEARCHPREFIX_PREFIX); + PagedResult<BowSearchPrefix> result = getProxy().findAllByCriteria(BowSearchPrefix.class, criteria); + List<BowSearchPrefix> prefix = new ArrayList<BowSearchPrefix>(result.getAll()); + log.debug("####################### prefix number ################### " + prefix.size()); + if (prefix.isEmpty()) { + // no prefix found, create default prefix for this request + String userId = user.getWikittyId(); + String prefixSeparator = BowConfig.getPrefixSeparator(); + + BowSearchPrefixImpl pWeb = new BowSearchPrefixImpl(); + pWeb.setBowUser(userId); + pWeb.setPrefix(BowConfig.getWebSearchPrefix() + prefixSeparator); + pWeb.setSearch(BowConfig.getSearchEngine()); + // TODO poussin 20130916 add default value in config for suggestion + + BowSearchPrefixImpl pTag = new BowSearchPrefixImpl(); + pTag.setBowUser(userId); + pTag.setPrefix(BowConfig.getTagSearchPrefix() + prefixSeparator); + pTag.setSearch("search.tag"); + pTag.setSuggestion("suggestion.tag"); + + BowSearchPrefixImpl pFullText = new BowSearchPrefixImpl(); + pFullText.setBowUser(userId); + pFullText.setPrefix(BowConfig.getFullTextSearchPrefix() + prefixSeparator); + pFullText.setSearch("search.fulltext"); + pFullText.setSuggestion("suggestion.fulltext"); + + BowSearchPrefixImpl pAlias = new BowSearchPrefixImpl(); + pAlias.setBowUser(userId); + pAlias.setPrefix(BowConfig.getAliasPrefix() + prefixSeparator); + pAlias.setSearch("search.alias"); + pAlias.setSuggestion("suggestion.alias"); + + BowSearchPrefixImpl pDefault = new BowSearchPrefixImpl(); + pDefault.getWikitty().replaceWith(pWeb.getWikitty(), true); + pDefault.setPrefix(""); + + BowSearchPrefixImpl pDefaultPrefix = new BowSearchPrefixImpl(); + pDefaultPrefix.getWikitty().replaceWith(pTag.getWikitty(), true); + pDefaultPrefix.setPrefix(prefixSeparator); + + proxy.store(pWeb, pTag, pFullText, pAlias, pDefault, pDefaultPrefix); + + prefix.add(pWeb); + prefix.add(pTag); + prefix.add(pFullText); + prefix.add(pAlias); + prefix.add(pDefault); + prefix.add(pDefaultPrefix); + + } + return prefix; + } + public void setUser(BowUser user) { // check if this user is admin String login = user.getLogin(); @@ -129,33 +195,33 @@ if (preference.getColors() == null) { preference.setColors(""); } - if (preference.getSearchEngineUrlResults() == null) { - preference.setSearchEngineUrlResults(BowConfig.getSearchEngine()); - } - if (preference.getSearchEngineUrlSuggestions() == null) { - preference.setSearchEngineUrlSuggestions(""); // TODO add default value in config - } - if (StringUtils.isBlank(preference.getPrefixSeparator())) { - preference.setPrefixSeparator(BowConfig.getPrefixSeparator()); - } - if (StringUtils.isBlank(preference.getTagSearchPrefix())) { - preference.setTagSearchPrefix(BowConfig.getTagSearchPrefix()); - } - if (StringUtils.isBlank(preference.getFullTextSearchPrefix())) { - preference.setFullTextSearchPrefix(BowConfig.getFullTextSearchPrefix()); - } - if (StringUtils.isBlank(preference.getWebSearchPrefix())) { - preference.setWebSearchPrefix(BowConfig.getWebSearchPrefix()); - } - if (StringUtils.isBlank(preference.getAliasPrefix())) { - preference.setAliasPrefix(BowConfig.getAliasPrefix()); - } - if (StringUtils.isBlank(preference.getDefaultPrefix())) { - preference.setDefaultPrefix(BowConfig.getDefaultPrefix()); - } - if (StringUtils.isBlank(preference.getDefaultAction())) { - preference.setDefaultAction(BowConfig.getDefaultAction()); - } +// if (preference.getSearchEngineUrlResults() == null) { +// preference.setSearchEngineUrlResults(BowConfig.getSearchEngine()); +// } +// if (preference.getSearchEngineUrlSuggestions() == null) { +// preference.setSearchEngineUrlSuggestions(""); // TODO add default value in config +// } +// if (StringUtils.isBlank(preference.getPrefixSeparator())) { +// preference.setPrefixSeparator(BowConfig.getPrefixSeparator()); +// } +// if (StringUtils.isBlank(preference.getTagSearchPrefix())) { +// preference.setTagSearchPrefix(BowConfig.getTagSearchPrefix()); +// } +// if (StringUtils.isBlank(preference.getFullTextSearchPrefix())) { +// preference.setFullTextSearchPrefix(BowConfig.getFullTextSearchPrefix()); +// } +// if (StringUtils.isBlank(preference.getWebSearchPrefix())) { +// preference.setWebSearchPrefix(BowConfig.getWebSearchPrefix()); +// } +// if (StringUtils.isBlank(preference.getAliasPrefix())) { +// preference.setAliasPrefix(BowConfig.getAliasPrefix()); +// } +// if (StringUtils.isBlank(preference.getDefaultPrefix())) { +// preference.setDefaultPrefix(BowConfig.getDefaultPrefix()); +// } +// if (StringUtils.isBlank(preference.getDefaultAction())) { +// preference.setDefaultAction(BowConfig.getDefaultAction()); +// } } public String getPermanentToken() { Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/AliasAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/AliasAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/AliasAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -27,6 +27,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.bow.BowBookmark; +import org.chorem.bow.BowUser; import org.nuiton.wikitty.WikittyProxy; import org.nuiton.wikitty.search.Criteria; import org.nuiton.wikitty.search.Search; @@ -80,7 +81,15 @@ BowBookmark bookmark = proxy.findByCriteria(BowBookmark.class, criteria); if (bookmark == null) { - bookmark = proxy.restore(BowBookmark.class, alias); + // not public alias, looking for private if user is logged + BowUser user = getBowSession().getUser(); + if (user != null) { + criteria = Search.query() + .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, user.getWikittyId()) + .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, alias) + .criteria(); + bookmark = proxy.findByCriteria(BowBookmark.class, criteria); + } } if (bookmark != null) { redirectTo = bookmark.getLink(); Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/admin/MigrateDataAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/admin/MigrateDataAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/admin/MigrateDataAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -27,8 +27,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.chorem.bow.BowMigration04To05; import org.chorem.bow.BowMigration06To11; +import org.chorem.bow.BowMigration11To12; import org.chorem.bow.BowSession; import org.chorem.bow.action.BowBaseAction; import org.nuiton.util.VersionUtil; @@ -71,14 +71,14 @@ if (session.isAdmin()) { //If is admin WikittyProxy proxy = getBowProxy(); - if (VersionUtil.equals(versionFrom, "0.4") - && VersionUtil.equals(versionTo, "0.5")) { - BowMigration04To05.migrate(proxy); - addActionMessage(_("bow.admin.dataMigration.success")); - } else if (VersionUtil.equals(versionFrom, "0.6") + if (VersionUtil.equals(versionFrom, "0.6") && VersionUtil.equals(versionTo, "1.1")) { BowMigration06To11.migrate(proxy); addActionMessage(_("bow.admin.dataMigration.success")); + } else if (VersionUtil.equals(versionFrom, "1.1") + && VersionUtil.equals(versionTo, "1.2")) { + BowMigration11To12.migrate(proxy); + addActionMessage(_("bow.admin.dataMigration.success")); } else { addActionMessage(String.format( "No migration found for %s to %s", Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchBaseAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchBaseAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchBaseAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -26,7 +26,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.chorem.bow.BowUser; +import org.apache.struts2.ServletActionContext; +import org.chorem.bow.BowSearchPrefix; import org.chorem.bow.action.BowBaseAction; /** @@ -49,21 +50,14 @@ protected String token; /** [in] la ligne de recherche soumise par l'utilisateur */ - protected String searchLine; + protected String search; - /** - * [out] le prefix trouve ou calculer par rapport a searchLine - * avoir acces a cette valeur, peut-etre utile dans certaine implantation - * de {@link #executeNotSupportedPrefixAction} - */ - protected String prefix; - - public String getSearchLine() { - return searchLine; + public String getSearch() { + return search; } - public void setSearchLine(String searchLine) { - this.searchLine = searchLine; + public void setSearch(String search) { + this.search = search; } /** @return the token */ @@ -76,60 +70,41 @@ this.token = token; } - public String getPrefix() { - return prefix; - } + abstract protected String executePrefixAction(BowSearchPrefix foundPrefix, String query); - abstract protected String executeTagSearchAction(String query); - - abstract protected String executeFulltextSearchAction(String query); - - abstract protected String executeWebSearchAction(String query); - - abstract protected String executeAliasSearchAction(String privateAlias); - - abstract protected String executeNotSupportedPrefixAction(String query); - @Override public String execute() { - BowUser user = getBowSession().getUser(); + System.out.println("######################### OpenSearchBaseAction enter #################" + search); + System.out.println("param:" + ServletActionContext.getRequest().getParameterMap()); - String prefixSeparator = user.getPrefixSeparator(); - prefix = StringUtils.substringBefore(searchLine, prefixSeparator); - String query = StringUtils.substringAfter(searchLine, prefixSeparator); + BowSearchPrefix defaultPrefix = null; + BowSearchPrefix foundPrefix = null; + String query; - if (log.isDebugEnabled()) { - log.debug(String.format("Cut '%s' with '%s' result is '%s' and '%s'", - searchLine, prefixSeparator, prefix, query)); + for (BowSearchPrefix prefix : getBowSession().getSearchPrefix()) { + String p = prefix.getPrefix(); + if (StringUtils.isBlank(p)) { + defaultPrefix = prefix; + } else if (StringUtils.startsWith(search, p)) { + foundPrefix = prefix; + break; + } } - if (StringUtils.isEmpty(prefix)) { - // on a le separateur mais pas de prefix - prefix = user.getDefaultPrefix(); - } else if (StringUtils.equals(searchLine, prefix)) { - // on a pas de separateur - prefix = user.getDefaultAction(); - query = searchLine; + if (foundPrefix == null) { + foundPrefix = defaultPrefix; } - if (log.isDebugEnabled()) { - log.debug(String.format("Prefix is '%s' and query '%s'", - prefix, query)); - } - - String result; - if (StringUtils.equals(prefix, user.getTagSearchPrefix())) { - result = executeTagSearchAction(query); - } else if (StringUtils.equals(prefix, user.getFullTextSearchPrefix())) { - result = executeFulltextSearchAction(query); - } else if (StringUtils.equals(prefix, user.getWebSearchPrefix())) { - result = executeWebSearchAction(query); - } else if (StringUtils.equals(prefix, user.getAliasPrefix())) { - result = executeAliasSearchAction(query); + if (foundPrefix == null) { + query = search; } else { - result = executeNotSupportedPrefixAction(query); + query = StringUtils.substringAfter(search, foundPrefix.getPrefix()); } + System.out.println("######################### OpenSearchBaseAction #################" + query + " - " + foundPrefix); + + String result = executePrefixAction(foundPrefix, query); return result; } + } Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchResultAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchResultAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchResultAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -23,19 +23,14 @@ */ package org.chorem.bow.action.opensearch; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.interceptor.ServletResponseAware; -import org.chorem.bow.BowBookmark; import org.chorem.bow.BowConfig; -import org.chorem.bow.BowUser; -import org.chorem.bow.BowUtils; -import org.nuiton.wikitty.WikittyProxy; -import org.nuiton.wikitty.search.Criteria; -import org.nuiton.wikitty.search.Search; import javax.servlet.http.HttpServletResponse; +import org.chorem.bow.BowSearchPrefix; +import org.nuiton.util.ApplicationConfig; /** * Traite toutes les demandes faite via l'opensearch @@ -64,62 +59,28 @@ this.response = response; } - protected String executeTagSearchAction(String query) { - redirectTo = BowUtils.redirectTo(query, null); - return SUCCESS; - } + @Override + protected String executePrefixAction(BowSearchPrefix foundPrefix, String query) { + String action; - protected String executeFulltextSearchAction(String query) { - redirectTo = BowUtils.redirectTo(null, query); - return SUCCESS; - } + ApplicationConfig config = BowConfig.getConfig(); - protected String executeWebSearchAction(String query) { - // Search on the chosen search engine - BowUser user = getBowSession().getUser(); + if (foundPrefix == null) { + action = BowConfig.getSearchEngine(); + } else { + action = foundPrefix.getSearch(); + } - String result = user.getSearchEngineUrlResults(); - if (StringUtils.isEmpty(result)) { - result = BowConfig.getSearchEngine(); + // des alias peuvent exister dans la configuration + String optionkey = "bow.prefix." + action; + if (config.hasOption(optionkey)) { + action = config.getOption(optionkey); } - result = result.replace("{searchTerms}", query); - result = response.encodeRedirectURL(result); - redirectTo = result; - return SUCCESS; - } - protected String executeAliasSearchAction(String privateAlias) { - BowUser user = getBowSession().getUser(); - WikittyProxy proxy = getBowProxy(); - Criteria criteria = Search.query() - .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, user.getWikittyId()) - .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, privateAlias) - .criteria(); - String bookmarkId = proxy.findIdByCriteria(criteria); + action = action.replace("{searchTerms}", query); + action = response.encodeRedirectURL(action); + redirectTo = action; - String result; - // si on retrouve l'alias prive on l'utilise, - // sinon on espere qu'il existe un alias public portant ce nom - if (bookmarkId != null) { - result = BowConfig.getAliasUrl() + bookmarkId + ".action"; - if (log.isDebugEnabled()) { - log.debug("Private alias found, redirect to: " + result); - } - } else { - result = BowConfig.getAliasUrl() + privateAlias + ".action"; - if (log.isDebugEnabled()) { - log.debug("Private alias not found, redirect to: " + result); - } - } - redirectTo = result; return SUCCESS; } - - @Override - protected String executeNotSupportedPrefixAction(String query) { - // prefix inconnu, on va sur la home - redirectTo = BowUtils.redirectTo(null, null); - return SUCCESS; - } - } Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchSuggestionAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchSuggestionAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/OpenSearchSuggestionAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -25,26 +25,25 @@ import com.opensymphony.xwork2.ActionContext; import org.apache.commons.io.input.ReaderInputStream; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.chorem.bow.BookmarkUtils; -import org.chorem.bow.BowBookmark; import org.chorem.bow.BowConfig; -import org.chorem.bow.BowUser; -import org.chorem.bow.BowUtils; -import org.nuiton.wikitty.WikittyProxy; -import org.nuiton.wikitty.entities.Wikitty; -import org.nuiton.wikitty.search.Criteria; -import org.nuiton.wikitty.search.FacetTopic; -import org.nuiton.wikitty.search.PagedResult; -import org.nuiton.wikitty.search.Search; import java.io.InputStream; import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.apache.struts2.ServletActionContext; +import org.chorem.bow.BowSearchPrefix; +import org.nuiton.util.ApplicationConfig; /** * Retourne les suggestions pour l'opensearch en fonction de ce qui a ete deja @@ -72,168 +71,73 @@ } @Override - protected String executeTagSearchAction(String query) { - if (log.isDebugEnabled()) { - log.debug(String.format("Start opensearch tag suggest for '%s'", query)); - } + protected String executePrefixAction(BowSearchPrefix foundPrefix, String query) { + String result = String.format("['%s', []]", query); + try { + log.trace("######################### executePrefixAction #################" + query + " - " + foundPrefix); + String action; - // preparation de la reponse. Un toString sur une liste retourne - // la bonne syntaxe pour une reponse json :) si on triche un peu - // en ajoutant des '' pour les chaines - List<Object> json = new ArrayList<Object>(); - List<String> completions = new ArrayList<String>(); - List<String> descriptions = new ArrayList<String>(); - List<String> queryUrls = new ArrayList<String>(); - - json.add("'" + query + "'"); - json.add(completions); - json.add(descriptions); - json.add(queryUrls); - - if (query != null) { - BowUser user = getBowSession().getUser(); - WikittyProxy proxy = getBowProxy(); - - // on ajoute * a la fin du dernier tag, car il n'est peut-etre pas fini - String searchLineStar = query + "*"; - - // on recupere le dernier tag en train d'etre ecrit - String lastTag; - if (query.contains(" ")) { - lastTag = StringUtils.substringAfterLast(query, " "); + ApplicationConfig config = BowConfig.getConfig(); + + if (foundPrefix == null) { + action = BowConfig.getSearchEngine(); } else { - lastTag = query; + action = foundPrefix.getSuggestion(); } - Set<String> searchLineList = BowUtils.getWords(searchLineStar); - - Search search = BookmarkUtils.addEqUser(Search.query(), user.getWikittyId()); - search.exteq(BowBookmark.EXT_WIKITTYLABEL); - search.contains(BowBookmark.FQ_FIELD_WIKITTYLABEL_LABELS, searchLineList); - - Criteria criteria = search - .criteria() - .setEndIndex(0) // on ne veut aucun resultat, c'est la facet dont on a besoin - .setFacetMinCount(1) // on demande meme les labels avec 1 seul item - .setFacetLimit(Integer.MAX_VALUE) // ne ne met pas -1 pour qu'il soit trie par ordre de count - .addFacetField(BowBookmark.FQ_FIELD_WIKITTYLABEL_LABELS); - - PagedResult<Wikitty> result = proxy.findAllByCriteria(criteria); - // lorsqu'on demande tout (facetLimit(-1)), les topics sont trie - // alphabetiquement pas besoin de les retrier - List<FacetTopic> topics = result.getTopic(BowBookmark.FQ_FIELD_WIKITTYLABEL_LABELS); - if (log.isTraceEnabled()) { - log.trace("all topics: %s" + topics); + // des alias peuvent exister dans la configuration + String optionkey = "bow.prefix." + action; + if (config.hasOption(optionkey)) { + action = config.getOption(optionkey); } - // on en retourne un suggestion que le meme nombre de tag qu'il souhaite - // voir affiche - int count = user.getTags(); - for (FacetTopic t : topics) { - // on ne met que les topics qui qui commence par lastTag - String completion = t.getTopicName(); - if (log.isTraceEnabled()) { - log.trace(String.format("'%s' startsWith '%s' ? ", completion, lastTag)); - } - if (completion.startsWith(lastTag)) { - String description = _("bow.opensearch.result", t.getCount()); - String tags = query + StringUtils.removeStart(completion, lastTag); - getConfig(); - String queryUrl = BowConfig.getBowUrl() + BowUtils.redirectTo(tags, null); + action = action.replace("{searchTerms}", URLEncoder.encode(query, "UTF-8")); - completions.add("'" + completion + "'"); - descriptions.add("'" + description + "'"); - queryUrls.add("'" + queryUrl + "'"); - - // on s'arrete si l'on en a assez - count--; - if (count <= 0) { - break; - } + if (!StringUtils.startsWith(action, "http")) { + String serveur = + ServletActionContext.getRequest().getScheme() + "://" + + ServletActionContext.getRequest().getServerName() + ":" + + ServletActionContext.getRequest().getServerPort() + + ServletActionContext.getRequest().getContextPath(); + if (!StringUtils.startsWith(action, "/")) { + action = "/" + action; } + action = serveur + action + "&token=" + getBowSession().getPermanentToken(); } - } - if (log.isDebugEnabled()) { - log.debug(String.format("opensearch suggest result: %s", json)); - } - inputStream = new ReaderInputStream(new StringReader(json.toString())); - return SUCCESS; - } - @Override - protected String executeFulltextSearchAction(String query) { - return executeNotSupportedPrefixAction(query); - } +// action = ServletActionContext.getResponse().encodeURL(action); + try { + log.debug("try to connect to : " + action); + // ne fonctionne pas (rien ne se passe, pas de requete envoyee :() +// result = Request.Get(action) +// .connectTimeout(1000) +// .socketTimeout(1000) +// .execute().returnContent().asString(); - @Override - protected String executeWebSearchAction(String query) { - return executeNotSupportedPrefixAction(query); - } - @Override - protected String executeAliasSearchAction(String privateAlias) { - if (log.isDebugEnabled()) { - log.debug(String.format("Start opensearch alias suggest for '%s'", privateAlias)); - } - - // preparation de la reponse. Un toString sur une liste retourne - // la bonne syntaxe pour une reponse json :) si on triche un peu - // en ajoutant des '' pour les chaines - List<Object> json = new ArrayList<Object>(); - List<String> completions = new ArrayList<String>(); - List<String> descriptions = new ArrayList<String>(); - List<String> queryUrls = new ArrayList<String>(); - - json.add("'" + privateAlias + "'"); - json.add(completions); - json.add(descriptions); - json.add(queryUrls); - - if (privateAlias != null) { - BowUser user = getBowSession().getUser(); - WikittyProxy proxy = getBowProxy(); - - // on ajoute * a la fin, car il n'est peut-etre pas fini - String privateAliasStar = privateAlias + "*"; - - Search search = BookmarkUtils.addEqUser(Search.query(), user.getWikittyId()); - search.eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, privateAliasStar); - - Criteria criteria = search.criteria() - .setEndIndex(15); // on recupere que les 15 premiers resultats - - PagedResult<BowBookmark> result = proxy.findAllByCriteria(BowBookmark.class, criteria); - - for (BowBookmark b : result) { - String completion = b.getPrivateAlias(); - String description = b.getDescription(); - String queryUrl = String.format("%s%s?token=%s", - BowConfig.getAliasUrl(), completion, token); - completions.add("'" + completion + "'"); - descriptions.add("'" + description + "'"); - queryUrls.add("'" + queryUrl + "'"); + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(action); + CloseableHttpResponse response = httpclient.execute(httpGet); + + try { + HttpEntity entity = response.getEntity(); + result = IOUtils.toString(entity.getContent()); + // ensure it is fully consumed + EntityUtils.consume(entity); + } finally { + response.close(); + } + } catch (Exception eee) { + log.info("Can't get result for url: " + action, eee); + } finally { + log.debug("suggestion: " + result); } - + } catch (UnsupportedEncodingException eee) { + log.info("Can't make suggestion for: " + query, eee); } - if (log.isDebugEnabled()) { - log.debug(String.format("opensearch alias suggest result: %s", json)); - } - inputStream = new ReaderInputStream(new StringReader(json.toString())); - return SUCCESS; - } - - /** - * On ne renvoie aucune suggestion - * - * @param query - * @return - */ - @Override - protected String executeNotSupportedPrefixAction(String query) { - String result = String.format("['%s', [], [], []]", query); inputStream = new ReaderInputStream(new StringReader(result)); + return SUCCESS; } - } \ No newline at end of file Added: trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/SuggestionAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/SuggestionAction.java (rev 0) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/SuggestionAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -0,0 +1,211 @@ +package org.chorem.bow.action.opensearch; + + +import java.io.InputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.bow.BookmarkUtils; +import org.chorem.bow.BowBookmark; +import org.chorem.bow.BowUser; +import org.chorem.bow.BowUtils; +import org.chorem.bow.action.BowBaseAction; +import org.nuiton.wikitty.WikittyProxy; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.search.Criteria; +import org.nuiton.wikitty.search.FacetTopic; +import org.nuiton.wikitty.search.PagedResult; +import org.nuiton.wikitty.search.Search; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class SuggestionAction extends BowBaseAction { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(SuggestionAction.class); + + /** [in] le token d'identification */ + protected String token; + /** [in] la requete pour lequel il faut trouver des suggesions */ + protected String q; + /** [out] le resultat de la suggestion **/ + protected transient InputStream inputStream; + + public void setToken(String token) { + this.token = token; + } + + public InputStream getInputStream() { + return inputStream; + } + + public String getQ() { + return q; + } + + public void setQ(String q) { + this.q = q; + } + + public String tag() { + if (log.isDebugEnabled()) { + log.debug(String.format("Start opensearch tag suggest for '%s'", q)); + } + + // preparation de la reponse. Un toString sur une liste retourne + // la bonne syntaxe pour une reponse json :) si on triche un peu + // en ajoutant des '' pour les chaines + List<Object> json = new ArrayList<Object>(); + List<String> completions = new ArrayList<String>(); +// List<String> descriptions = new ArrayList<String>(); +// List<String> queryUrls = new ArrayList<String>(); + + json.add("'" + q + "'"); + json.add(completions); +// json.add(descriptions); +// json.add(queryUrls); + + if (q != null) { + BowUser user = getBowSession().getUser(); + WikittyProxy proxy = getBowProxy(); + + // on ajoute * a la fin du dernier tag, car il n'est peut-etre pas fini + String searchLineStar = q + "*"; + + // on recupere le dernier tag en train d'etre ecrit + String firstTag; + String lastTag; + if (q.contains(" ")) { + firstTag = StringUtils.substringBeforeLast(q, " ") + " "; + lastTag = StringUtils.substringAfterLast(q, " "); + } else { + firstTag = ""; + lastTag = q; + } + + Set<String> searchLineList = BowUtils.getWords(searchLineStar); + + Search search = BookmarkUtils.addEqUser(Search.query(), user.getWikittyId()); + search.exteq(BowBookmark.EXT_WIKITTYLABEL); + search.contains(BowBookmark.FQ_FIELD_WIKITTYLABEL_LABELS, searchLineList); + + Criteria criteria = search + .criteria() + .setEndIndex(0) // on ne veut aucun resultat, c'est la facet dont on a besoin + .setFacetMinCount(1) // on demande meme les labels avec 1 seul item + .setFacetLimit(Integer.MAX_VALUE) // ne ne met pas -1 pour qu'il soit trie par ordre de count + .addFacetField(BowBookmark.FQ_FIELD_WIKITTYLABEL_LABELS); + + PagedResult<Wikitty> result = proxy.findAllByCriteria(criteria); + // lorsqu'on demande tout (facetLimit(-1)), les topics sont trie + // alphabetiquement pas besoin de les retrier + List<FacetTopic> topics = result.getTopic(BowBookmark.FQ_FIELD_WIKITTYLABEL_LABELS); + if (log.isTraceEnabled()) { + log.trace("all topics: %s" + topics); + } + + // on en retourne un suggestion que le meme nombre de tag qu'il souhaite + // voir affiche + int count = user.getTags(); + for (FacetTopic t : topics) { + // on ne met que les topics qui qui commence par lastTag + String completion = t.getTopicName(); + if (log.isTraceEnabled()) { + log.trace(String.format("'%s' startsWith '%s' ? ", completion, lastTag)); + } + if (completion.startsWith(lastTag)) { +// String description = _("bow.opensearch.result", t.getCount()); +// String tags = q + StringUtils.removeStart(completion, lastTag); +// String queryUrl = BowConfig.getBowUrl() + BowUtils.redirectTo(tags, null); + + completions.add("'" + firstTag + completion + "'"); +// descriptions.add("'" + description + "'"); +// queryUrls.add("'" + queryUrl + "'"); + + // on s'arrete si l'on en a assez + count--; + if (count <= 0) { + break; + } + } + } + } + if (log.isDebugEnabled()) { + log.debug(String.format("opensearch suggest result: %s", json)); + } + inputStream = new ReaderInputStream(new StringReader(json.toString())); + return SUCCESS; + + } + + public String fulltext() { + String result = String.format("['%s', []]", q); + inputStream = new ReaderInputStream(new StringReader(result)); + return SUCCESS; + } + + public String alias() { + if (log.isDebugEnabled()) { + log.debug(String.format("Start opensearch alias suggest for '%s'", q)); + } + + // preparation de la reponse. Un toString sur une liste retourne + // la bonne syntaxe pour une reponse json :) si on triche un peu + // en ajoutant des '' pour les chaines + List<Object> json = new ArrayList<Object>(); + List<String> completions = new ArrayList<String>(); +// List<String> descriptions = new ArrayList<String>(); +// List<String> queryUrls = new ArrayList<String>(); + + json.add("'" + q + "'"); + json.add(completions); +// json.add(descriptions); +// json.add(queryUrls); + + if (q != null) { + BowUser user = getBowSession().getUser(); + WikittyProxy proxy = getBowProxy(); + + // on ajoute * a la fin, car il n'est peut-etre pas fini + String privateAliasStar = q + "*"; + + Search search = BookmarkUtils.addEqUser(Search.query(), user.getWikittyId()); + search.or(). + eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, privateAliasStar). + eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PUBLICALIAS, privateAliasStar); + + Criteria criteria = search.criteria() + .setEndIndex(15); // on recupere que les 15 premiers resultats + + PagedResult<BowBookmark> result = proxy.findAllByCriteria(BowBookmark.class, criteria); + + for (BowBookmark b : result) { + String completion = b.getPrivateAlias(); +// String description = b.getDescription(); +// String queryUrl = String.format("%s%s?token=%s", +// BowConfig.getAliasUrl(), completion, token); + completions.add("'" + completion + "'"); +// descriptions.add("'" + description + "'"); +// queryUrls.add("'" + queryUrl + "'"); + } + + } + if (log.isDebugEnabled()) { + log.debug(String.format("opensearch alias suggest result: %s", json)); + } + inputStream = new ReaderInputStream(new StringReader(json.toString())); + return SUCCESS; + } + +} Property changes on: trunk/bow-ui/src/main/java/org/chorem/bow/action/opensearch/SuggestionAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -24,7 +24,6 @@ package org.chorem.bow.action.preference; import com.opensymphony.xwork2.ActionContext; -import org.apache.commons.lang.StringUtils; import org.chorem.bow.BowBookmark; import org.chorem.bow.BowImport; import org.chorem.bow.BowProxy; @@ -43,6 +42,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.chorem.bow.BowSearchPrefix; /** * Change les preferences de l'utilisateur (couleur, password, email, ...) @@ -79,24 +79,8 @@ protected String bookmarksHomePage; - protected String searchEngineUrlSuggestions; + protected List<BowSearchPrefix> searchPrefix; - protected String searchEngineUrlResults; - - protected String separator; - - protected String tagPrefix; - - protected String fulltextPrefix; - - protected String webPrefix; - - protected String aliasPrefix; - - protected DefaultPrefix defaultPrefix; - - protected DefaultPrefix defaultAction; - protected List<FacetTopic> labels; protected String[] selectedLabels; @@ -165,82 +149,17 @@ this.bookmarksHomePage = bookmarksHomePage; } - /** @return the searchEngineUrlSuggestions */ - public String getSearchEngineUrlSuggestions() { - return searchEngineUrlSuggestions; + public List<BowSearchPrefix> getSearchPrefix() { + if (searchPrefix == null) { + loadSearchPrefixPref(); + } + return searchPrefix; } - /** @param searchEngineUrlSuggestions the searchEngineUrlSuggestions to set */ - public void setSearchEngineUrlSuggestions(String searchEngineUrlSuggestions) { - this.searchEngineUrlSuggestions = searchEngineUrlSuggestions; + public void setSearchPrefix(List<BowSearchPrefix> searchPrefix) { + this.searchPrefix = searchPrefix; } - /** @return the searchEngineUrlResults */ - public String getSearchEngineUrlResults() { - return searchEngineUrlResults; - } - - /** @param searchEngineUrlResults the searchEngineUrlResults to set */ - public void setSearchEngineUrlResults(String searchEngineUrlResults) { - this.searchEngineUrlResults = searchEngineUrlResults; - } - - public String getSeparator() { - return separator; - } - - public void setSeparator(String separator) { - this.separator = separator; - } - - public String getTagPrefix() { - return tagPrefix; - } - - public void setTagPrefix(String tagPrefix) { - this.tagPrefix = tagPrefix; - } - - public String getFulltextPrefix() { - return fulltextPrefix; - } - - public void setFulltextPrefix(String fulltextPrefix) { - this.fulltextPrefix = fulltextPrefix; - } - - public String getWebPrefix() { - return webPrefix; - } - - public void setWebPrefix(String webPrefix) { - this.webPrefix = webPrefix; - } - - public String getAliasPrefix() { - return aliasPrefix; - } - - public void setAliasPrefix(String aliasPrefix) { - this.aliasPrefix = aliasPrefix; - } - - public DefaultPrefix getDefaultPrefix() { - return defaultPrefix; - } - - public void setDefaultPrefix(String defaultPrefix) { - this.defaultPrefix = DefaultPrefix.valueOf(defaultPrefix); - } - - public DefaultPrefix getDefaultAction() { - return defaultAction; - } - - public void setDefaultAction(String defaultAction) { - this.defaultAction = DefaultPrefix.valueOf(defaultAction); - } - /** @return the email */ public String getEmail() { return email; @@ -352,6 +271,7 @@ break; case SITE_PREF: loadSitePref(); + loadSearchPrefixPref(); break; case LABELS: loadLabels(); @@ -387,55 +307,13 @@ setColors(user.getColors()); setTagsNb(String.valueOf(user.getTags())); setBookmarksHomePage(String.valueOf(user.getBookmarks())); - setSearchEngineUrlSuggestions(user.getSearchEngineUrlSuggestions()); - setSearchEngineUrlResults(user.getSearchEngineUrlResults()); - - setSeparator(user.getPrefixSeparator()); - setTagPrefix(user.getTagSearchPrefix()); - setFulltextPrefix(user.getFullTextSearchPrefix()); - setWebPrefix(user.getWebSearchPrefix()); - setAliasPrefix(user.getAliasPrefix()); - - defaultAction = getDefaultConst(user, user.getDefaultAction()); - defaultPrefix = getDefaultConst(user, user.getDefaultPrefix()); - } - protected String getDefaultValue(BowUser user, DefaultPrefix constValue) { - String result = user.getAliasPrefix(); - switch (constValue) { - case TAG: - result = user.getTagSearchPrefix(); - break; - case FULLTEXT: - result = user.getFullTextSearchPrefix(); - break; - case WEB: - result = user.getWebSearchPrefix(); - break; - case ALIAS: - result = user.getAliasPrefix(); - break; - default: - break; - } - return result; + protected void loadSearchPrefixPref() { + BowSession session = getBowSession(); + this.searchPrefix = session.getSearchPrefix(); } - protected DefaultPrefix getDefaultConst(BowUser user, String value) { - DefaultPrefix result = DefaultPrefix.ALIAS; - if (StringUtils.equals(value, user.getTagSearchPrefix())) { - result = DefaultPrefix.TAG; - } else if (StringUtils.equals(value, user.getFullTextSearchPrefix())) { - result = DefaultPrefix.FULLTEXT; - } else if (StringUtils.equals(value, user.getWebSearchPrefix())) { - result = DefaultPrefix.WEB; - } else if (StringUtils.equals(value, user.getAliasPrefix())) { - result = DefaultPrefix.ALIAS; - } - return result; - } - /** Charge la liste des imports que l'utilisateur a fait */ protected void loadImport() { BowSession session = getBowSession(); Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java 2013-09-19 09:27:16 UTC (rev 357) @@ -27,6 +27,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.bow.BowProxy; +import org.chorem.bow.BowSearchPrefix; +import org.chorem.bow.BowSearchPrefixImpl; import org.chorem.bow.BowSession; import org.chorem.bow.BowUser; @@ -44,6 +46,16 @@ private static final long serialVersionUID = 1L; + protected int removedPrefix = -1; + + public void setRemovedPrefix(int removedPrefix) { + this.removedPrefix = removedPrefix; + } + + public int getRemovedPrefix() { + return removedPrefix; + } + /** * ACTION STRUTS * <p/> @@ -65,19 +77,9 @@ if (StringUtils.isNotBlank(bookmarksHomePage)) { preference.setBookmarks(Integer.valueOf(bookmarksHomePage)); } - preference.setSearchEngineUrlSuggestions(searchEngineUrlSuggestions); - preference.setSearchEngineUrlResults(searchEngineUrlResults); - preference.setPrefixSeparator(separator); + searchPrefix = proxy.store(searchPrefix); - preference.setTagSearchPrefix(tagPrefix); - preference.setFullTextSearchPrefix(fulltextPrefix); - preference.setWebSearchPrefix(webPrefix); - preference.setAliasPrefix(aliasPrefix); - - preference.setDefaultAction(getDefaultValue(preference, defaultAction)); - preference.setDefaultPrefix(getDefaultValue(preference, defaultPrefix)); - preference = proxy.store(preference); getBowSession().setUser(preference); } catch (Exception eee) { @@ -93,4 +95,51 @@ } + public String addPrefix() { + String result = SUCCESS; + try { + BowSession session = getBowSession(); + BowProxy proxy = session.getProxy(); + + BowSearchPrefix prefix = new BowSearchPrefixImpl(); + prefix.setBowUser(session.getUser().getWikittyId()); + + searchPrefix.add(prefix); + proxy.store(searchPrefix); + // force reload to have right order by + searchPrefix = null; + } catch (Exception eee) { + result = ERROR; + addActionError(_("bow.error.internal")); + log.error("Can't change site preference", eee); + } finally { + // on recharge les data apres l'action pour l'affichage + // sauf celle du site qui sont deja les bonnes + load(PreferenceType.SITE_PREF); + } + return result; + } + + public String removePrefix() { + String result = SUCCESS; + try { + log.debug("########################## removedPrefix ############## " + removedPrefix); + if (removedPrefix >= 0) { + BowSession session = getBowSession(); + BowProxy proxy = session.getProxy(); + + BowSearchPrefix p = searchPrefix.remove(removedPrefix); + proxy.delete(p); + } + } catch (Exception eee) { + result = ERROR; + addActionError(_("bow.error.internal")); + log.error("Can't change site preference", eee); + } finally { + // on recharge les data apres l'action pour l'affichage + // sauf celle du site qui sont deja les bonnes + load(PreferenceType.SITE_PREF); + } + return result; + } } Added: trunk/bow-ui/src/main/java/org/chorem/bow/interceptor/LaxLoginInterceptor.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/interceptor/LaxLoginInterceptor.java (rev 0) +++ trunk/bow-ui/src/main/java/org/chorem/bow/interceptor/LaxLoginInterceptor.java 2013-09-19 09:27:16 UTC (rev 357) @@ -0,0 +1,71 @@ +/* + * #%L + * bow + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.bow.interceptor; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import org.chorem.bow.BowSession; +import org.chorem.bow.BowUser; +import org.chorem.bow.BowUtils; + +import java.util.Map; + +/** + * Interceptor used to login user is inforamtion existe, otherwize do nothing + */ +public class LaxLoginInterceptor extends AbstractInterceptor { + private static final long serialVersionUID = -7520186185205372272L; + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + Map<String, Object> session = ActionContext.getContext().getSession(); + + BowSession bowSession = BowSession.getBowSession(session); + BowUser user = bowSession.getUser(); + String result = null; + + //If the user isn't logged in + if (user == null) { + Map<String, Object> params = ActionContext.getContext().getParameters(); + //Retrieves the token value in URL + String[] token = (String[]) params.get("token"); + + if (token != null && !token[0].isEmpty()) { + //Retrieves the user by token + user = BowUtils.checkToken(bowSession, token[0]); + + //If the token is valid + if (user != null) { + //Authenticates the user + bowSession.setUser(user); + } + } + } + + result = invocation.invoke(); + + return result; + } +} Property changes on: trunk/bow-ui/src/main/java/org/chorem/bow/interceptor/LaxLoginInterceptor.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties =================================================================== --- trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties 2013-09-19 09:27:16 UTC (rev 357) @@ -1,8 +1,9 @@ bow.action.locale.english=English -bow.action.locale.french=Fran\u00e7ais +bow.action.locale.french=Fran\u00E7ais bow.admin.dataMigration.success=Data migration successful bow.admin.dataMigration04to05=Migrate all data from 0.4 to 0.5 -bow.admin.dataMigration05to06=Migrate all data from 0.5 to 1.1 +bow.admin.dataMigration05to06=Migrate all data from 1.1 to 1.2 +bow.admin.dataMigration11to12= bow.admin.dataReindexation=All data reindexation bow.admin.forbidden=You don't have admin rights \! bow.admin.home=Return to the home page @@ -24,6 +25,10 @@ bow.config.application.version.description=application version bow.config.bow.addressFrom.description=mail from address bow.config.bow.admins.description=admins email address list +bow.config.bow.prefix.search.alias.description= +bow.config.bow.prefix.search.fulltext.description= +bow.config.bow.prefix.suggestion.alias.description= +bow.config.bow.prefix.suggestion.fulltext.description= bow.config.bow.smtpServer.description=smtp server address bow.config.bow.url.description=Web server bow URL bow.config.configFileName.description=bow configuration file @@ -36,6 +41,8 @@ bow.config.opensearch.tag.search.prefix.description=prefix for tag search bow.config.opensearch.web.search.prefix.description=prefix for web search bow.config.search.engine.description=URL of web search engine to use +bow.config.sprefix.search.tag.description= +bow.config.sprefix.suggestion.tag.description= bow.error.internal=An internal error occurred, please contact an administrator if the problem persists bow.footer.bugreport=Bug report bow.footer.license=AGPL License Modified: trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties =================================================================== --- trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties 2013-09-19 09:27:16 UTC (rev 357) @@ -1,53 +1,60 @@ bow.action.locale.english=English -bow.action.locale.french=Fran\u00e7ais -bow.admin.dataMigration.success=Les donn\u00e9es ont \u00e9t\u00e9 migr\u00e9es avec succ\u00e8s -bow.admin.dataMigration04to05=Migrer toutes les donn\u00e9es de la version 0.4 \u00e0 0.5 -bow.admin.dataMigration05to06=Migrer toutes les donn\u00e9es de la version 0.5 \u00e0 1.1 -bow.admin.dataReindexation=R\u00e9indexation des donn\u00e9es -bow.admin.forbidden=Vous n'\u00eates pas administrateur \! +bow.action.locale.french=Fran\u00E7ais +bow.admin.dataMigration.success=Les donn\u00E9es ont \u00E9t\u00E9 migr\u00E9es avec succ\u00E8s +bow.admin.dataMigration04to05=Migrer toutes les donn\u00E9es de la version 0.4 \u00E0 0.5 +bow.admin.dataMigration05to06=Migrer toutes les donn\u00E9es de la version 1.1 \u00E0 1.2 +bow.admin.dataMigration11to12= +bow.admin.dataReindexation=R\u00E9indexation des donn\u00E9es +bow.admin.forbidden=Vous n'\u00EAtes pas administrateur \! bow.admin.home=Retour sur la page d''accueil bow.admin.panel=Panneau d''administration -bow.admin.reIndexationDone=Les donn\u00e9es ont bien \u00e9t\u00e9 r\u00e9index\u00e9es -bow.alias.already.exists=L''alias {0} existe d\u00e9j\u00e0 -bow.alias.bookmarkId.unknown=Il n''y a pas de marque-page correspondant \u00e0 l''identifiant {0} -bow.bookmark.add.successful=Marque-page ajout\u00e9 avec succ\u00e8s -bow.bookmark.badFileFormat=Mauvais format de fichier de favoris \: import impossible (le format de type Netscape n'est pas support\u00e9) +bow.admin.reIndexationDone=Les donn\u00E9es ont bien \u00E9t\u00E9 r\u00E9index\u00E9es +bow.alias.already.exists=L''alias {0} existe d\u00E9j\u00E0 +bow.alias.bookmarkId.unknown=Il n''y a pas de marque-page correspondant \u00E0 l''identifiant {0} +bow.bookmark.add.successful=Marque-page ajout\u00E9 avec succ\u00E8s +bow.bookmark.badFileFormat=Mauvais format de fichier de favoris \: import impossible (le format de type Netscape n'est pas support\u00E9) bow.bookmark.description=Description -bow.bookmark.import.delete.successful=Les marque-pages import\u00e9s ont \u00e9t\u00e9 supprim\u00e9s avec succ\u00e8s -bow.bookmark.import.successful=Les marque-pages ont \u00e9t\u00e9 import\u00e9s avec succ\u00e8s -bow.bookmark.remove.successful=Le marque-page a \u00e9t\u00e9 supprim\u00e9 avec succ\u00e8s -bow.bookmark.tag.deleted=Le tag a \u00e9t\u00e9 supprim\u00e9 avec succ\u00e8s +bow.bookmark.import.delete.successful=Les marque-pages import\u00E9s ont \u00E9t\u00E9 supprim\u00E9s avec succ\u00E8s +bow.bookmark.import.successful=Les marque-pages ont \u00E9t\u00E9 import\u00E9s avec succ\u00E8s +bow.bookmark.remove.successful=Le marque-page a \u00E9t\u00E9 supprim\u00E9 avec succ\u00E8s +bow.bookmark.tag.deleted=Le tag a \u00E9t\u00E9 supprim\u00E9 avec succ\u00E8s bow.bookmark.tags=Tags -bow.bookmark.update.successful=Le marque-page a \u00e9t\u00e9 mis \u00e0 jour avec succ\u00e8s +bow.bookmark.update.successful=Le marque-page a \u00E9t\u00E9 mis \u00E0 jour avec succ\u00E8s bow.bookmarks.noBookmarks=Pas de marque-page bow.config.alias.url.description=Url public du serveur d'alias bow.config.application.version.description=Version de l'application bow.config.bow.addressFrom.description=Adresse expediteur des emails bow.config.bow.admins.description=Liste des emails des admins de l'application +bow.config.bow.prefix.search.alias.description= +bow.config.bow.prefix.search.fulltext.description= +bow.config.bow.prefix.suggestion.alias.description= +bow.config.bow.prefix.suggestion.fulltext.description= bow.config.bow.smtpServer.description=Adresse du serveur de mail bow.config.bow.url.description=Url public du serveur bow bow.config.configFileName.description=Fichier de configuration de bow -bow.config.data.dir.description=R\u00e9pertoire de stockage des donn\u00e9es +bow.config.data.dir.description=R\u00E9pertoire de stockage des donn\u00E9es bow.config.opensearch.alias.prefix.description=Prefix de redirection via l'alias -bow.config.opensearch.default.action.description=action par d\u00e9faut -bow.config.opensearch.default.prefix.description=Prefix par d\u00e9faut +bow.config.opensearch.default.action.description=action par d\u00E9faut +bow.config.opensearch.default.prefix.description=Prefix par d\u00E9faut bow.config.opensearch.fulltext.search.prefix.description=Fulltext -bow.config.opensearch.prefix.separator.description=S\u00e9parateur de pr\u00e9fix -bow.config.opensearch.tag.search.prefix.description=Pr\u00e9fix de recherche par tag +bow.config.opensearch.prefix.separator.description=S\u00E9parateur de pr\u00E9fix +bow.config.opensearch.tag.search.prefix.description=Pr\u00E9fix de recherche par tag bow.config.opensearch.web.search.prefix.description=prefix de recherche sur le web -bow.config.search.engine.description=Url du moteur de recherche Web \u00e0 utiliser +bow.config.search.engine.description=Url du moteur de recherche Web \u00E0 utiliser +bow.config.sprefix.search.tag.description= +bow.config.sprefix.suggestion.tag.description= bow.error.internal=Une erreur interne est survenue, merci de contacter un administrateur si cette erreur persiste bow.footer.bugreport=Rapport de bug bow.footer.license=Licence AGPL bow.footer.userSupport=Support utilisateur bow.forgotPassword.emailDoesntExist=Cette adresse email n''existe pas bow.forgotpwd.submit=Envoyer -bow.forgotpwd.title=Vous avez oubli\u00e9 votre mot de passe ? -bow.home.latestBookmarks=Les derniers marque-pages ajout\u00e9s -bow.home.mostUsedBookmarks=Les marque-pages les plus utilis\u00e9s +bow.forgotpwd.title=Vous avez oubli\u00E9 votre mot de passe ? +bow.home.latestBookmarks=Les derniers marque-pages ajout\u00E9s +bow.home.mostUsedBookmarks=Les marque-pages les plus utilis\u00E9s bow.home.title=Accueil -bow.login.admin.failback=Probl\u00e8me d'authentification, vous devriez reconstruire l'index via la page d'admin -bow.login.authenticationFailure=Soit votre adresse email n''existe pas, soit votre mot de passe est eronn\u00e9 +bow.login.admin.failback=Probl\u00E8me d'authentification, vous devriez reconstruire l'index via la page d'admin +bow.login.authenticationFailure=Soit votre adresse email n''existe pas, soit votre mot de passe est eronn\u00E9 bow.login.email=Email bow.login.email.required=Veuillez entrer votre adresse email bow.login.email.wrongformat=Votre adresse email est invalide @@ -57,68 +64,68 @@ bow.login.repeatPassword.required=Veuillez retaper votre mot de passe bow.login.submit=Connexion bow.login.title=Connexion -bow.mail.badFormat=Votre adresse email est mal form\u00e9e \: aucun mail n''a pu \u00eatre envoy\u00e9 +bow.mail.badFormat=Votre adresse email est mal form\u00E9e \: aucun mail n''a pu \u00EAtre envoy\u00E9 bow.mail.sendError=Une erreur s''est produite lors de l''envoi du mail -bow.opensearch.result=%s r\u00e9sultats -bow.preference.opensearch.prefix.separator=Separateur de pr\u00e9fix +bow.opensearch.result=%s r\u00E9sultats +bow.preference.opensearch.prefix.separator=Separateur de pr\u00E9fix bow.preferences.badCurrentPassword=Votre mot de passe actuel est incorrect -bow.preferences.bookmarksHomePage=Nombre de marque-pages affich\u00e9s +bow.preferences.bookmarksHomePage=Nombre de marque-pages affich\u00E9s bow.preferences.colors=Couleur du site bow.preferences.confirmNewPassword=Confirmez votre mot de passe bow.preferences.currentPassword=Mot de passe actuel -bow.preferences.emailAldyExists=Cette addresse email est d\u00e9j\u00e0 utilis\u00e9e par un autre compte +bow.preferences.emailAldyExists=Cette addresse email est d\u00E9j\u00E0 utilis\u00E9e par un autre compte bow.preferences.export.bookmarks=Exporter les marque-pages bow.preferences.import.bookmarks=Importer des marques-pages bow.preferences.import.submit=Importer bow.preferences.importExport=Import / Export -bow.preferences.importedBookmarks=Marque-pages import\u00e9s +bow.preferences.importedBookmarks=Marque-pages import\u00E9s bow.preferences.labels=Gestion des labels bow.preferences.labels.delete.submit=Supprimer bow.preferences.labels.name.field=Nouveau nom bow.preferences.labels.rename.submit=Renomer bow.preferences.newPassword=Nouveau mot de passe -bow.preferences.noImportedBookmarks=Aucun marque-page import\u00e9 +bow.preferences.noImportedBookmarks=Aucun marque-page import\u00E9 bow.preferences.opensearch.alias.prefix=Alias -bow.preferences.opensearch.default.action=action par d\u00e9faut -bow.preferences.opensearch.default.prefix=Prefix par d\u00e9faut +bow.preferences.opensearch.default.action=action par d\u00E9faut +bow.preferences.opensearch.default.prefix=Prefix par d\u00E9faut bow.preferences.opensearch.fulltext.search.prefix=Recherche Fulltext -bow.preferences.opensearch.prefix=Pr\u00e9fix -bow.preferences.opensearch.prefix.separator=S\u00e9parateur de pr\u00e9fix +bow.preferences.opensearch.prefix=Pr\u00E9fix +bow.preferences.opensearch.prefix.separator=S\u00E9parateur de pr\u00E9fix bow.preferences.opensearch.tag.search.prefix=Recherche par tag bow.preferences.opensearch.value=Valeur bow.preferences.opensearch.web.search.prefix=Recherche Web -bow.preferences.regenPermToken=Reg\u00e9n\u00e9rer le token permanent -bow.preferences.searchEngineUrlResults=Search Engine URL Results ('{'searchTerms'}' sera remplac\u00e9 par votre recherche) +bow.preferences.regenPermToken=Reg\u00E9n\u00E9rer le token permanent +bow.preferences.searchEngineUrlResults=Search Engine URL Results ('{'searchTerms'}' sera remplac\u00E9 par votre recherche) bow.preferences.searchEngineUrlSuggestions=Search Engine URL Suggestions -bow.preferences.siteLook=Pr\u00e9f\u00e9rences du site +bow.preferences.siteLook=Pr\u00E9f\u00E9rences du site bow.preferences.submit=Changer bow.preferences.tagsManagement=Edition des tags -bow.preferences.tagsNb=Nombre de tags affich\u00e9s sur le nuage de tags -bow.preferences.title=Pr\u00e9f\u00e9rences -bow.preferences.update.successful=Vos pr\u00e9f\u00e9rences ont \u00e9t\u00e9 mises \u00e0 jour avec succ\u00e8s +bow.preferences.tagsNb=Nombre de tags affich\u00E9s sur le nuage de tags +bow.preferences.title=Pr\u00E9f\u00E9rences +bow.preferences.update.successful=Vos pr\u00E9f\u00E9rences ont \u00E9t\u00E9 mises \u00E0 jour avec succ\u00E8s bow.preferences.userInfo=Informations utilisateur -bow.register.emailAldyUsed=Cette adresse email est d\u00e9j\u00e0 utilis\u00e9e -bow.register.invalidLogin=Une erreur s''est produite pendant l''enregistrement de vos informations, merci d''essayer \u00e0 nouveau +bow.register.emailAldyUsed=Cette adresse email est d\u00E9j\u00E0 utilis\u00E9e +bow.register.invalidLogin=Une erreur s''est produite pendant l''enregistrement de vos informations, merci d''essayer \u00E0 nouveau bow.register.mailEmail=Votre email bow.register.mailHi=Bonjour bow.register.mailPwd=Votre mot de passe bow.register.mailSubject=[bow] Vos informations utilisateur -bow.register.pwdDontMatch=Les mots de passe sont diff\u00e9rents +bow.register.pwdDontMatch=Les mots de passe sont diff\u00E9rents bow.register.submit=S''enregistrer bow.register.title=S''enregistrer bow.requiredstring=${getText(fieldKey)} est obligatoire -bow.rightMenu.addUrl.link=Ajouter une entr\u00e9e +bow.rightMenu.addUrl.link=Ajouter une entr\u00E9e bow.rightMenu.admin=Admin bow.rightMenu.bookmark.addModify=Ajouter / Modifier bow.rightMenu.bookmark.alias=ALIAS bow.rightMenu.bookmark.link=URL bow.rightMenu.bookmark.name=DESC bow.rightMenu.bookmark.permanentLink=Ajouter un bookmark (permanent) -bow.rightMenu.bookmark.permanentLinkDescription=Ajoutez ce lien \u00e0 vos favoris pour pouvoir bookmarker vos liens dans le futur. Ce lien est toujours disponible \! +bow.rightMenu.bookmark.permanentLinkDescription=Ajoutez ce lien \u00E0 vos favoris pour pouvoir bookmarker vos liens dans le futur. Ce lien est toujours disponible \! bow.rightMenu.bookmark.submit=Sauvegarder bow.rightMenu.bookmark.tags=TAGS bow.rightMenu.bookmark.temporaryLink=Ajouter un bookmark (session) -bow.rightMenu.bookmark.temporaryLinkDescription=Ajoutez ce lien \u00e0 vos favoris pour pouvoir bookmarker vos liens dans le futur. Ce lien est seulement disponible tant que vous \u00eates connect\u00e9 sur le site \! +bow.rightMenu.bookmark.temporaryLinkDescription=Ajoutez ce lien \u00E0 vos favoris pour pouvoir bookmarker vos liens dans le futur. Ce lien est seulement disponible tant que vous \u00EAtes connect\u00E9 sur le site \! bow.rightMenu.chromiumExtension=Extension pour chromium bow.rightMenu.extensions=Extensions bow.rightMenu.externSearchEngine=Web @@ -127,7 +134,7 @@ bow.rightMenu.help=Aide bow.rightMenu.import.submit=Importer bow.rightMenu.importBookmarks=Importer des marque-pages -bow.rightMenu.logout=D\u00e9connexion +bow.rightMenu.logout=D\u00E9connexion bow.rightMenu.search=Recherche bow.rightMenu.search.tags=par tags bow.rightMenu.token.permanent=Token permanent @@ -139,18 +146,18 @@ bow.search.descdate=Date desc. bow.search.descname=Nom desc. bow.search.found=Total\: -bow.search.order.ascClick=Les r\u00e9sultats de votre recherche ont \u00e9t\u00e9 tri\u00e9s par nombre de clics ascendants -bow.search.order.ascDate=Les r\u00e9sultats de votre recherche ont \u00e9t\u00e9 tri\u00e9s par date ascendante -bow.search.order.ascName=Les r\u00e9sultats de votre recherche ont \u00e9t\u00e9 tri\u00e9s par nom ascendant -bow.search.order.descClick=Les r\u00e9sultats de votre recherche ont \u00e9t\u00e9 tri\u00e9s par nombre de clics descendants -bow.search.order.descDate=Les r\u00e9sultats de votre recherche ont \u00e9t\u00e9 tri\u00e9s par date descendante -bow.search.order.descName=Les r\u00e9sultats de votre recherche ont \u00e9t\u00e9 tri\u00e9s par nom descendant +bow.search.order.ascClick=Les r\u00E9sultats de votre recherche ont \u00E9t\u00E9 tri\u00E9s par nombre de clics ascendants +bow.search.order.ascDate=Les r\u00E9sultats de votre recherche ont \u00E9t\u00E9 tri\u00E9s par date ascendante +bow.search.order.ascName=Les r\u00E9sultats de votre recherche ont \u00E9t\u00E9 tri\u00E9s par nom ascendant +bow.search.order.descClick=Les r\u00E9sultats de votre recherche ont \u00E9t\u00E9 tri\u00E9s par nombre de clics descendants +bow.search.order.descDate=Les r\u00E9sultats de votre recherche ont \u00E9t\u00E9 tri\u00E9s par date descendante +bow.search.order.descName=Les r\u00E9sultats de votre recherche ont \u00E9t\u00E9 tri\u00E9s par nom descendant bow.search.orderby=Trier par -bow.search.results.deleted=Les r\u00e9sultats de la recherche ont \u00e9t\u00e9 supprim\u00e9s avec succ\u00e8s +bow.search.results.deleted=Les r\u00E9sultats de la recherche ont \u00E9t\u00E9 supprim\u00E9s avec succ\u00E8s bow.search.submit=Rechercher bow.search.title=Recherche -bow.token.generate.successful=Le token a \u00e9t\u00e9 reg\u00e9n\u00e9r\u00e9 avec succ\u00e8s -popup.addurl.alias.private=Alias priv\u00e9 +bow.token.generate.successful=Le token a \u00E9t\u00E9 reg\u00E9n\u00E9r\u00E9 avec succ\u00E8s +popup.addurl.alias.private=Alias priv\u00E9 popup.addurl.alias.public=Alias public popup.addurl.link=Url popup.addurl.name=Description Modified: trunk/bow-ui/src/main/resources/log4j.properties =================================================================== --- trunk/bow-ui/src/main/resources/log4j.properties 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/resources/log4j.properties 2013-09-19 09:27:16 UTC (rev 357) @@ -30,10 +30,10 @@ log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] (%30.30c) %m%n # package level -log4j.logger.org.chorem.bow=DEBUG -log4j.logger.org.chorem.bow.web.time=DEBUG -log4j.logger.org.nuiton.wikitty.WikittyProxy.TimeLog=DEBUG -log4j.logger.org.nuiton.wikitty.services.WikittyServiceSecurity.TimeLog=DEBUG -log4j.logger.org.apache.struts2.dispatcher.mapper=DEBUG +##log4j.logger.org.chorem.bow=DEBUG +##log4j.logger.org.chorem.bow.web.time=DEBUG +##log4j.logger.org.nuiton.wikitty.WikittyProxy.TimeLog=DEBUG +##log4j.logger.org.nuiton.wikitty.services.WikittyServiceSecurity.TimeLog=DEBUG +##log4j.logger.org.apache.struts2.dispatcher.mapper=DEBUG log4j.logger.org.apache.solr=WARN log4j.logger.org.apache.jcs=WARN Modified: trunk/bow-ui/src/main/resources/struts.xml =================================================================== --- trunk/bow-ui/src/main/resources/struts.xml 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/resources/struts.xml 2013-09-19 09:27:16 UTC (rev 357) @@ -45,11 +45,13 @@ +--> <package name="publicArea" extends="struts-default"> <interceptors> + <interceptor name="laxLogin" class="org.chorem.bow.interceptor.LaxLoginInterceptor"/> <interceptor-stack name="publicAreaStack"> <interceptor-ref name="timer"> <param name="logLevel">debug</param> <param name="logCategory">org.chorem.bow.web.time.render</param> </interceptor-ref> + <interceptor-ref name="laxLogin"/> <interceptor-ref name="defaultStack"> <param name="store.operationMode">AUTOMATIC</param> <param name="fileUpload.allowedExtensions">.html</param> @@ -86,10 +88,6 @@ <interceptor-stack name="restrictedAreaStack"> <interceptor-ref name="login"/> <interceptor-ref name="publicAreaStack"/> - <interceptor-ref name="timer"> - <param name="logLevel">debug</param> - <param name="logCategory">org.chorem.bow.web.time.action</param> - </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="restrictedAreaStack"/> @@ -101,6 +99,13 @@ <result name="success" type="redirect">${redirectTo}</result> <result name="error">/WEB-INF/jsp/error.jsp</result> </action> + <action name="alias" class="org.chorem.bow.action.AliasAction"> + <result name="success" type="redirect">${redirectTo}</result> + <result name="error">/WEB-INF/jsp/error.jsp</result> + </action> + <action name="*Xml"> + <result>/WEB-INF/jsp/{1}Xml.jsp</result> + </action> </package> <package name="login" extends="loginArea"> @@ -160,6 +165,14 @@ <action name="openSearchResult" class="org.chorem.bow.action.opensearch.OpenSearchResultAction"> <result type="redirect">${redirectTo}</result> </action> + <action name="suggestion-*" class="org.chorem.bow.action.opensearch.SuggestionAction" method="{1}"> + <result type="stream"> + <param name="contentType">application/x-suggestions+json</param> + <param name="inputName">inputStream</param> + <param name="contentDisposition">inline</param> + <param name="allowCaching">false</param> + </result> + </action> <action name="openSearchSuggestion" class="org.chorem.bow.action.opensearch.OpenSearchSuggestionAction"> <!-- <result>/WEB-INF/jsp/suggestions.jsp</result> --> <result type="stream"> @@ -169,9 +182,6 @@ <param name="allowCaching">false</param> </result> </action> - <action name="*Xml"> - <result>/WEB-INF/jsp/{1}Xml.jsp</result> - </action> </package> <package name="preference" extends="restrictedArea"> @@ -199,6 +209,16 @@ <result>/WEB-INF/jsp/preferences.jsp</result> </action> + <action name="addPrefix" class="org.chorem.bow.action.preference.UpdateSiteAction" method="addPrefix"> + <result name="error">/WEB-INF/jsp/preferences.jsp</result> + <result>/WEB-INF/jsp/preferences.jsp</result> + </action> + + <action name="removePrefix" class="org.chorem.bow.action.preference.UpdateSiteAction" method="removePrefix"> + <result name="error">/WEB-INF/jsp/preferences.jsp</result> + <result>/WEB-INF/jsp/preferences.jsp</result> + </action> + <action name="adminlabels" class="org.chorem.bow.action.preference.AdminTagAction"> <result name="error">/WEB-INF/jsp/preferences.jsp</result> <result>/WEB-INF/jsp/preferences.jsp</result> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/admin.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/admin.jsp 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/admin.jsp 2013-09-19 09:27:16 UTC (rev 357) @@ -44,8 +44,8 @@ <s:if test="#session.BowSession.isAdmin()"> <ul id="adminActions"> <li><s:a action="reIndexation"><s:text name="bow.admin.dataReindexation" /></s:a></li> - <li><s:a action="migrateData?versionFrom=0.4&versionTo=0.5"><s:text name="bow.admin.dataMigration04to05" /></s:a></li> <li><s:a action="migrateData?versionFrom=0.6&versionTo=1.1"><s:text name="bow.admin.dataMigration05to06" /></s:a></li> + <li><s:a action="migrateData?versionFrom=1.1&versionTo=1.2"><s:text name="bow.admin.dataMigration11to12" /></s:a></li> <li><s:a action="home" id="homePage"><s:text name="bow.admin.home" /></s:a></li> </ul> </s:if> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/permanentXml.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/permanentXml.jsp 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/permanentXml.jsp 2013-09-19 09:27:16 UTC (rev 357) @@ -27,17 +27,17 @@ <% String url = BowConfig.getBowUrl(); -%> +%><?xml version="1.0" encoding="UTF-8"?> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/" xmlns:s="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" xmlns:jsp="http://java.sun.com/JSP/Page"> <ShortName>Bow (permanent)</ShortName> <Description>bookmarkSearch</Description> - <InputEncoding>inputEncoding</InputEncoding> + <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16" type="image/ico"><%=url%>img/bow.gif</Image> <s:set var="token" value="#session.BowSession.getPermanentToken()" /> - <Url type="text/html" method="GET" template="<%=url%>openSearchResult.action?token=${token}&searchLine={searchTerms}" /> - <Url type="application/x-suggestions+json" method="GET" template="<%=url%>openSearchSuggestion.action?token=${token}&searchLine={searchTerms}" /> + <Url type="text/html" method="get" template="<%=url%>openSearchResult.action?token=${token}&search={searchTerms}" /> + <Url type="application/x-suggestions+json" method="get" template="<%=url%>openSearchSuggestion.action?token=${token}&search={searchTerms}" /> <moz:SearchForm><%=url%></moz:SearchForm> </OpenSearchDescription> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp 2013-09-19 09:27:16 UTC (rev 357) @@ -25,11 +25,11 @@ <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@taglib prefix="s" uri="/struts-tags" %> -<% +<%-- PreferenceBaseAction action = PreferenceBaseAction.getAction(); PreferenceBaseAction.DefaultPrefix defaultAction = action.getDefaultAction(); PreferenceBaseAction.DefaultPrefix defaultPrefix = action.getDefaultPrefix(); -%> +--%> <html xmlns:s="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" xmlns:jsp="http://java.sun.com/JSP/Page"> @@ -110,65 +110,41 @@ <div class="formFrame fond"> <h3><s:text name="bow.preferences.siteLook"/></h3> <br/> - <s:form action="updateSitePref" theme="simple"> + + <script type="text/javascript"> + function setRemoveIndex(removeIndex) { + $('input[name="removedPrefix"]').val(removeIndex); + document.updateSitePref.submit(); + return false; + } + </script> + + <s:form name="updateSitePref" action="updateSitePref" theme="simple"> + <s:hidden name="removedPrefix" value="-1"/> + <s:text name="bow.preferences.tagsNb"/><br/> <s:textfield name="tagsNb" labelposition="top"/><br/> <s:text name="bow.preferences.bookmarksHomePage"/><br/> <s:textfield name="bookmarksHomePage" labelposition="top"/><br/> - <s:text name="bow.preferences.searchEngineUrlSuggestions"/><br/> - <s:textfield name="searchEngineUrlSuggestions" - labelposition="top"/><br/> - - <s:text name="bow.preferences.searchEngineUrlResults"/><br/> - <s:textfield name="searchEngineUrlResults" - size="50" - labelposition="top"/><br/> - - <s:text name="bow.preference.opensearch.prefix.separator"/> - <s:textfield name="separator" size="1" maxLength="1"/><br/> - <table> <tr> <th><s:text name="bow.preferences.opensearch.prefix"/></th> <th><s:text name="bow.preferences.opensearch.value"/></th> - <th><s:text name="bow.preferences.opensearch.default.prefix"/></th> - <th><s:text name="bow.preferences.opensearch.default.action"/></th> + <th><s:text name="bow.preferences.searchEngineUrlSuggestions"/></th> </tr> + + <s:iterator value="searchPrefix" status="stat"> <tr> - <td><s:text name="bow.preferences.opensearch.tag.search.prefix"/></td> - <td><s:textfield name="tagPrefix" size="1" maxLength="1"/></td> - <td><input type="radio" name="defaultPrefix" value="<%=PreferenceBaseAction.DefaultPrefix.TAG%>" - <%=(defaultPrefix==PreferenceBaseAction.DefaultPrefix.TAG?"checked='true'":"")%>/></td> - <td><input type="radio" name="defaultAction" value="<%=PreferenceBaseAction.DefaultPrefix.TAG%>" - <%=(defaultAction==PreferenceBaseAction.DefaultPrefix.TAG?"checked='true'":"")%>/></td> + <td><s:textfield name="searchPrefix[%{#stat.index}].prefix" value="%{prefix}"/></td> + <td><s:textfield name="searchPrefix[%{#stat.index}].search" value="%{search}"/></td> + <td><s:textfield name="searchPrefix[%{#stat.index}].suggestion" value="%{suggestion}"/></td> + <td><s:submit action="removePrefix" value="X" onclick="return setRemoveIndex(%{#stat.index})"></s:submit></td> </tr> - <tr> - <td><s:text name="bow.preferences.opensearch.fulltext.search.prefix"/></td> - <td><s:textfield name="fulltextPrefix" size="1" maxLength="1"/></td> - <td><input type="radio" name="defaultPrefix" value="<%=PreferenceBaseAction.DefaultPrefix.FULLTEXT%>" - <%=(defaultPrefix==PreferenceBaseAction.DefaultPrefix.FULLTEXT?"checked='true'":"")%>/></td> - <td><input type="radio" name="defaultAction" value="<%=PreferenceBaseAction.DefaultPrefix.FULLTEXT%>" - <%=(defaultAction==PreferenceBaseAction.DefaultPrefix.FULLTEXT?"checked='true'":"")%>/></td> - </tr> - <tr> - <td><s:text name="bow.preferences.opensearch.web.search.prefix"/></td> - <td><s:textfield name="webPrefix" size="1" maxLength="1"/></td> - <td><input type="radio" name="defaultPrefix" value="<%=PreferenceBaseAction.DefaultPrefix.WEB%>" - <%=(defaultPrefix==PreferenceBaseAction.DefaultPrefix.WEB?"checked='true'":"")%>/></td> - <td><input type="radio" name="defaultAction" value="<%=PreferenceBaseAction.DefaultPrefix.WEB%>" - <%=(defaultAction==PreferenceBaseAction.DefaultPrefix.WEB?"checked='true'":"")%>/></td> - <tr> - <td><s:text name="bow.preferences.opensearch.alias.prefix"/></td> - <td><s:textfield name="aliasPrefix" size="1" maxLength="1"/></td> - <td><input type="radio" name="defaultPrefix" value="<%=PreferenceBaseAction.DefaultPrefix.ALIAS%>" - <%=(defaultPrefix==PreferenceBaseAction.DefaultPrefix.ALIAS?"checked='true'":"")%>/></td> - <td><input type="radio" name="defaultAction" value="<%=PreferenceBaseAction.DefaultPrefix.ALIAS%>" - <%=(defaultAction==PreferenceBaseAction.DefaultPrefix.ALIAS?"checked='true'":"")%>/></td> - </tr> - </tr> + </s:iterator> </table> + <s:submit action="addPrefix" value="add prefix"></s:submit> <s:hidden name="update" value="site"/> <s:submit key="bow.preferences.submit" name="submit"/> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/temporaryXml.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/temporaryXml.jsp 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/temporaryXml.jsp 2013-09-19 09:27:16 UTC (rev 357) @@ -24,20 +24,19 @@ <%@page contentType="text/xml" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <%@page import="org.chorem.bow.BowConfig" %> - <% String url = BowConfig.getBowUrl(); -%> +%><?xml version="1.0" encoding="UTF-8"?> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/" xmlns:s="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" xmlns:jsp="http://java.sun.com/JSP/Page"> <ShortName>Bow (temporary)</ShortName> <Description>bookmarkSearch</Description> - <InputEncoding>inputEncoding</InputEncoding> + <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16" type="image/ico"><%=url%>img/bow.gif</Image> <s:set var="token" value="%{#session.BowSession.getTemporaryToken()}" /> - <Url type="text/html" method="GET" template="<%=url%>openSearchResult.action?token=${token}&searchLine={searchTerms}" /> - <Url type="application/x-suggestions+json" method="GET" template="<%=url%>openSearchSuggestion.action?token=${token}&search={searchTerms}" /> + <Url type="text/html" method="get" template="<%=url%>openSearchResult.action?token=${token}&search={searchTerms}" /> + <Url type="application/x-suggestions+json" method="get" template="<%=url%>openSearchSuggestion.action?token=${token}&search={searchTerms}" /> <moz:SearchForm><%=url%></moz:SearchForm> </OpenSearchDescription> Modified: trunk/bow-ui/src/main/xmi/README =================================================================== --- trunk/bow-ui/src/main/xmi/README 2013-08-09 10:07:03 UTC (rev 356) +++ trunk/bow-ui/src/main/xmi/README 2013-09-19 09:27:16 UTC (rev 357) @@ -1,2 +1,2 @@ bow-0.4.zargo data model for bow 0.4 and previous -bow.zargo data model for current bow version +bow-model.zargo data model for current bow version Added: trunk/bow-ui/src/main/xmi/bow-model.zargo =================================================================== (Binary files differ) Property changes on: trunk/bow-ui/src/main/xmi/bow-model.zargo ___________________________________________________________________ Added: svn:mime-type + application/zip
participants (1)
-
bpoussin@users.chorem.org