This commit is contained in:
Shinsuke Sugaya 2014-01-25 15:25:43 +09:00
parent 6f3df3811b
commit 446f14257a
19 changed files with 1996 additions and 8 deletions

View file

@ -0,0 +1,352 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.action.admin.dict;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import jp.sf.fess.Constants;
import jp.sf.fess.crud.CommonConstants;
import jp.sf.fess.crud.CrudMessageException;
import jp.sf.fess.crud.util.SAStrutsUtil;
import jp.sf.fess.dict.userdict.UserDictItem;
import jp.sf.fess.form.admin.dict.UserDictForm;
import jp.sf.fess.helper.SystemHelper;
import jp.sf.fess.pager.UserDictPager;
import jp.sf.fess.service.UserDictService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codelibs.sastruts.core.annotation.Token;
import org.codelibs.sastruts.core.exception.SSCActionMessagesException;
import org.seasar.framework.beans.util.Beans;
import org.seasar.framework.util.StringUtil;
import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;
import org.seasar.struts.exception.ActionMessagesException;
public class UserDictAction {
private static final Log log = LogFactory.getLog(UserDictAction.class);
@Resource
@ActionForm
protected UserDictForm userDictForm;
@Resource
protected UserDictService userDictService;
@Resource
protected UserDictPager userDictPager;
@Resource
protected SystemHelper systemHelper;
public List<UserDictItem> userDictItemItems;
public String getHelpLink() {
return systemHelper.getHelpLink("dict");
}
protected String displayList(final boolean redirect) {
// page navi
userDictItemItems = userDictService.getUserDictList(
userDictForm.dictId, userDictPager);
// restore from pager
Beans.copy(userDictPager, userDictForm.searchParams)
.excludes(CommonConstants.PAGER_CONVERSION_RULE).execute();
if (redirect) {
return "index?dictId=" + userDictForm.dictId + "&redirect=true";
} else {
return "index.jsp";
}
}
@Execute(validator = false, input = "error.jsp")
public String index() {
return displayList(false);
}
@Execute(validator = false, input = "error.jsp", urlPattern = "list/{dictId}/{pageNumber}")
public String list() {
// page navi
if (StringUtil.isNotBlank(userDictForm.pageNumber)) {
try {
userDictPager.setCurrentPageNumber(Integer
.parseInt(userDictForm.pageNumber));
} catch (final NumberFormatException e) {
if (log.isDebugEnabled()) {
log.debug("Invalid value: " + userDictForm.pageNumber, e);
}
}
}
return displayList(false);
}
@Execute(validator = false, input = "error.jsp")
public String search() {
Beans.copy(userDictForm.searchParams, userDictPager)
.excludes(CommonConstants.PAGER_CONVERSION_RULE).execute();
return displayList(false);
}
@Execute(validator = false, input = "error.jsp")
public String reset() {
userDictPager.clear();
return displayList(false);
}
@Execute(validator = false, input = "error.jsp")
public String back() {
return displayList(false);
}
@Token(save = true, validate = false)
@Execute(validator = false, input = "error.jsp")
public String editagain() {
return "edit.jsp";
}
@Execute(validator = false, input = "error.jsp", urlPattern = "confirmpage/{dictId}/{crudMode}/{id}")
public String confirmpage() {
if (userDictForm.crudMode != CommonConstants.CONFIRM_MODE) {
throw new ActionMessagesException("errors.crud_invalid_mode",
new Object[] { CommonConstants.CONFIRM_MODE,
userDictForm.crudMode });
}
loadUserDict();
return "confirm.jsp";
}
@Token(save = true, validate = false)
@Execute(validator = false, input = "error.jsp")
public String createpage() {
// page navi
userDictForm.initialize();
userDictForm.crudMode = CommonConstants.CREATE_MODE;
return "edit.jsp";
}
@Token(save = true, validate = false)
@Execute(validator = false, input = "error.jsp", urlPattern = "editpage/{dictId}/{crudMode}/{id}")
public String editpage() {
if (userDictForm.crudMode != CommonConstants.EDIT_MODE) {
throw new ActionMessagesException("errors.crud_invalid_mode",
new Object[] { CommonConstants.EDIT_MODE,
userDictForm.crudMode });
}
loadUserDict();
return "edit.jsp";
}
@Token(save = true, validate = false)
@Execute(validator = false, input = "error.jsp")
public String editfromconfirm() {
userDictForm.crudMode = CommonConstants.EDIT_MODE;
loadUserDict();
return "edit.jsp";
}
@Token(save = false, validate = true, keep = true)
@Execute(validator = true, input = "edit.jsp")
public String confirmfromcreate() {
return "confirm.jsp";
}
@Token(save = false, validate = true, keep = true)
@Execute(validator = true, input = "edit.jsp")
public String confirmfromupdate() {
return "confirm.jsp";
}
@Token(save = true, validate = false)
@Execute(validator = false, input = "error.jsp", urlPattern = "deletepage/{dictId}/{crudMode}/{id}")
public String deletepage() {
if (userDictForm.crudMode != CommonConstants.DELETE_MODE) {
throw new ActionMessagesException("errors.crud_invalid_mode",
new Object[] { CommonConstants.DELETE_MODE,
userDictForm.crudMode });
}
loadUserDict();
return "confirm.jsp";
}
@Token(save = true, validate = false)
@Execute(validator = false, input = "error.jsp")
public String deletefromconfirm() {
userDictForm.crudMode = CommonConstants.DELETE_MODE;
loadUserDict();
return "confirm.jsp";
}
@Token(save = false, validate = true)
@Execute(validator = true, input = "edit.jsp")
public String create() {
try {
final UserDictItem userDictItem = createUserDict();
userDictService.store(userDictForm.dictId, userDictItem);
SAStrutsUtil.addSessionMessage("success.crud_create_crud_table");
return displayList(true);
} catch (final ActionMessagesException e) {
log.error(e.getMessage(), e);
throw e;
} catch (final CrudMessageException e) {
log.error(e.getMessage(), e);
throw new SSCActionMessagesException(e, e.getMessageId(),
e.getArgs());
} catch (final Exception e) {
log.error(e.getMessage(), e);
throw new SSCActionMessagesException(e,
"errors.crud_failed_to_create_crud_table");
}
}
@Token(save = false, validate = true)
@Execute(validator = true, input = "edit.jsp")
public String update() {
try {
final UserDictItem userDictItem = createUserDict();
userDictService.store(userDictForm.dictId, userDictItem);
SAStrutsUtil.addSessionMessage("success.crud_update_crud_table");
return displayList(true);
} catch (final ActionMessagesException e) {
log.error(e.getMessage(), e);
throw e;
} catch (final CrudMessageException e) {
log.error(e.getMessage(), e);
throw new SSCActionMessagesException(e, e.getMessageId(),
e.getArgs());
} catch (final Exception e) {
log.error(e.getMessage(), e);
throw new SSCActionMessagesException(e,
"errors.crud_failed_to_update_crud_table");
}
}
@Token(save = false, validate = true)
@Execute(validator = false, input = "error.jsp")
public String delete() {
if (userDictForm.crudMode != CommonConstants.DELETE_MODE) {
throw new ActionMessagesException("errors.crud_invalid_mode",
new Object[] { CommonConstants.DELETE_MODE,
userDictForm.crudMode });
}
try {
final UserDictItem userDictItem = userDictService.getUserDict(
userDictForm.dictId, createKeyMap());
if (userDictItem == null) {
// throw an exception
throw new ActionMessagesException(
"errors.crud_could_not_find_crud_table",
new Object[] { userDictForm.id });
}
userDictService.delete(userDictForm.dictId, userDictItem);
SAStrutsUtil.addSessionMessage("success.crud_delete_crud_table");
return displayList(true);
} catch (final ActionMessagesException e) {
log.error(e.getMessage(), e);
throw e;
} catch (final CrudMessageException e) {
log.error(e.getMessage(), e);
throw new SSCActionMessagesException(e, e.getMessageId(),
e.getArgs());
} catch (final Exception e) {
log.error(e.getMessage(), e);
throw new SSCActionMessagesException(e,
"errors.crud_failed_to_delete_crud_table");
}
}
protected void loadUserDict() {
final UserDictItem userDictItem = userDictService.getUserDict(
userDictForm.dictId, createKeyMap());
if (userDictItem == null) {
// throw an exception
throw new ActionMessagesException(
"errors.crud_could_not_find_crud_table",
new Object[] { userDictForm.id });
}
userDictForm.id = Long.toString(userDictItem.getId());
userDictForm.token = userDictItem.getToken();
userDictForm.segmentation = userDictItem.getSegmentation();
userDictForm.reading = userDictItem.getReading();
userDictForm.pos = userDictItem.getPos();
}
protected UserDictItem createUserDict() {
UserDictItem userDictItem;
if (userDictForm.crudMode == CommonConstants.EDIT_MODE) {
userDictItem = userDictService.getUserDict(userDictForm.dictId,
createKeyMap());
if (userDictItem == null) {
// throw an exception
throw new ActionMessagesException(
"errors.crud_could_not_find_crud_table",
new Object[] { userDictForm.id });
}
} else {
userDictItem = new UserDictItem(0, Constants.EMPTY_STRING,
Constants.EMPTY_STRING, Constants.EMPTY_STRING,
Constants.EMPTY_STRING);
}
userDictItem.setNewToken(userDictForm.token);
userDictItem.setNewSegmentation(userDictForm.segmentation);
userDictItem.setNewReading(userDictForm.reading);
userDictItem.setNewPos(userDictForm.pos);
return userDictItem;
}
protected Map<String, String> createKeyMap() {
final Map<String, String> keys = new HashMap<String, String>();
keys.put("id", userDictForm.id);
return keys;
}
}

View file

@ -23,8 +23,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import jp.sf.fess.dict.synonym.SynonymFile;
import org.seasar.extension.timer.TimeoutManager;
import org.seasar.extension.timer.TimeoutTarget;
import org.seasar.extension.timer.TimeoutTask;
@ -70,7 +68,10 @@ public class DictionaryManager {
final Collection<DictionaryFile<? extends DictionaryItem>> values = fileMap
.values();
return values.toArray(new SynonymFile[values.size()]);
@SuppressWarnings("unchecked")
final DictionaryFile<? extends DictionaryItem>[] list = new DictionaryFile[values
.size()];
return values.toArray(list);
}
public DictionaryFile<? extends DictionaryItem> getDictionaryFile(

View file

@ -117,7 +117,15 @@ public class SynonymFile extends DictionaryFile<SynonymItem> {
@Override
public synchronized void update(final SynonymItem item) {
reload(new SynonymUpdater(file, item));
SynonymUpdater updater = null;
try {
updater = new SynonymUpdater(file, item);
reload(updater);
} finally {
if (updater != null) {
updater.close();
}
}
}
@Override
@ -125,7 +133,15 @@ public class SynonymFile extends DictionaryFile<SynonymItem> {
final SynonymItem synonymItem = item;
synonymItem.setNewInputs(new String[0]);
synonymItem.setNewOutputs(new String[0]);
reload(new SynonymUpdater(file, synonymItem));
SynonymUpdater updater = null;
try {
updater = new SynonymUpdater(file, synonymItem);
reload(updater);
} finally {
if (updater != null) {
updater.close();
}
}
}
protected void reload(final SynonymUpdater updater) {
@ -213,9 +229,6 @@ public class SynonymFile extends DictionaryFile<SynonymItem> {
+ file.getAbsolutePath(), e);
} finally {
IOUtils.closeQuietly(reader);
if (updater != null) {
updater.close();
}
}
}

View file

@ -0,0 +1,311 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.dict.userdict;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import jp.sf.fess.Constants;
import jp.sf.fess.dict.DictionaryException;
import jp.sf.fess.dict.DictionaryFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.analysis.ja.util.CSVUtil;
public class UserDictFile extends DictionaryFile<UserDictItem> {
private static final String USERDICT = "userDict";
private final File file;
List<UserDictItem> userDictItemList;
public UserDictFile(final File file) {
this.file = file;
}
@Override
public String getType() {
return USERDICT;
}
@Override
public String getName() {
return file.getAbsolutePath();
}
@Override
public UserDictItem get(final long id) {
for (final UserDictItem userDictItem : userDictItemList) {
if (id == userDictItem.getId()) {
return userDictItem;
}
}
return null;
}
@Override
public synchronized PagingList<UserDictItem> selectList(final int offset,
final int size) {
if (userDictItemList == null) {
reload(null);
}
if (offset >= userDictItemList.size() || offset < 0) {
return new PagingList<UserDictItem>(
Collections.<UserDictItem> emptyList(), offset, size,
userDictItemList.size());
}
int toIndex = offset + size;
if (toIndex > userDictItemList.size()) {
toIndex = userDictItemList.size();
}
return new PagingList<UserDictItem>(userDictItemList.subList(offset,
toIndex), offset, size, userDictItemList.size());
}
@Override
public synchronized void insert(final UserDictItem item) {
final UserDictItem userDictItem = item;
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file, true), Constants.UTF_8));
bw.newLine();
bw.write(userDictItem.toLineString());
bw.flush();
long nextId = 1;
if (!userDictItemList.isEmpty()) {
final UserDictItem lastItem = userDictItemList
.get(userDictItemList.size() - 1);
nextId = lastItem.getId() + 1;
}
userDictItemList.add(new UserDictItem(nextId, userDictItem
.getNewToken(), userDictItem.getNewSegmentation(),
userDictItem.getNewReading(), userDictItem.getNewPos()));
} catch (final IOException e) {
throw new DictionaryException("Failed to write: " + item, e);
} finally {
IOUtils.closeQuietly(bw);
}
}
@Override
public synchronized void update(final UserDictItem item) {
UserDictUpdater updater = null;
try {
updater = new UserDictUpdater(file, item);
reload(updater);
} finally {
if (updater != null) {
updater.close();
}
}
}
@Override
public synchronized void delete(final UserDictItem item) {
final UserDictItem userDictItem = item;
userDictItem.setNewToken(Constants.EMPTY_STRING);
UserDictUpdater updater = null;
try {
updater = new UserDictUpdater(file, userDictItem);
reload(updater);
} finally {
if (updater != null) {
updater.close();
}
}
}
protected void reload(final UserDictUpdater updater) {
final List<UserDictItem> itemList = new ArrayList<UserDictItem>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file), Constants.UTF_8));
long id = 0;
String line = null;
while ((line = reader.readLine()) != null) {
// Remove comments
line = line.replaceAll("#.*$", "");
// Skip empty lines or comment lines
if (line.trim().length() == 0) {
if (updater != null) {
updater.write(line);
}
continue;
}
final String[] values = CSVUtil.parse(line);
String token = null;
String segmentation = null;
String reading = null;
String pos = null;
switch (values.length) {
case 4:
pos = values[3];
case 3:
reading = values[2];
case 2:
segmentation = values[1];
case 1:
token = values[0];
default:
break;
}
id++;
final UserDictItem item = new UserDictItem(id, token,
segmentation, reading, pos);
if (updater != null) {
final UserDictItem newItem = updater.write(item);
if (newItem != null) {
itemList.add(newItem);
} else {
id--;
}
} else {
itemList.add(item);
}
}
if (updater != null) {
updater.commit();
}
userDictItemList = itemList;
} catch (final IOException e) {
throw new DictionaryException("Failed to parse "
+ file.getAbsolutePath(), e);
} finally {
IOUtils.closeQuietly(reader);
}
}
protected static class UserDictUpdater {
protected boolean isCommit = false;
protected File oldFile;
protected File newFile;
protected Writer writer;
protected UserDictItem item;
protected UserDictUpdater(final File file, final UserDictItem newItem) {
try {
newFile = File.createTempFile(USERDICT, ".txt");
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(newFile), Constants.UTF_8));
} catch (final IOException e) {
if (newFile != null) {
newFile.delete();
}
throw new DictionaryException(
"Failed to write a userDict file.", e);
}
oldFile = file;
item = newItem;
}
public UserDictItem write(final UserDictItem oldItem) {
try {
if (item.getId() == oldItem.getId() && item.isUpdated()) {
if (item.equals(oldItem)) {
try {
if (!item.isDeleted()) {
// update
writer.write(item.toLineString());
writer.write(Constants.LINE_SEPARATOR);
return new UserDictItem(item.getId(),
item.getNewToken(),
item.getNewSegmentation(),
item.getNewReading(), item.getNewPos());
} else {
return null;
}
} finally {
item.setNewToken(null);
}
} else {
throw new DictionaryException(
"UserDict file was updated: old=" + oldItem
+ " : new=" + item);
}
} else {
writer.write(oldItem.toLineString());
writer.write(Constants.LINE_SEPARATOR);
return oldItem;
}
} catch (final IOException e) {
throw new DictionaryException("Failed to write: " + oldItem
+ " -> " + item, e);
}
}
public void write(final String line) {
try {
writer.write(line);
writer.write(Constants.LINE_SEPARATOR);
} catch (final IOException e) {
throw new DictionaryException("Failed to write: " + line, e);
}
}
public void commit() {
isCommit = true;
}
public void close() {
try {
writer.flush();
} catch (final IOException e) {
// ignore
}
IOUtils.closeQuietly(writer);
if (isCommit) {
try {
FileUtils.copyFile(newFile, oldFile);
newFile.delete();
} catch (final IOException e) {
throw new DictionaryException("Failed to replace "
+ oldFile.getAbsolutePath() + " with "
+ newFile.getAbsolutePath(), e);
}
} else {
newFile.delete();
}
}
}
}

View file

@ -0,0 +1,208 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.dict.userdict;
import jp.sf.fess.dict.DictionaryItem;
public class UserDictItem extends DictionaryItem {
private final String token;
private final String segmentation;
private final String reading;
private final String pos;
private String newToken;
private String newSegmentation;
private String newReading;
private String newPos;
public UserDictItem(final long id, final String token,
final String segmentation, final String reading, final String pos) {
this.id = id;
this.token = token;
this.segmentation = segmentation;
this.reading = reading;
this.pos = pos;
if (id == 0) {
// create
newToken = token;
newSegmentation = segmentation;
newReading = reading;
newPos = pos;
}
}
public String getNewToken() {
return newToken;
}
public void setNewToken(final String newToken) {
this.newToken = newToken;
}
public String getNewSegmentation() {
return newSegmentation;
}
public void setNewSegmentation(final String newSegmentation) {
this.newSegmentation = newSegmentation;
}
public String getNewReading() {
return newReading;
}
public void setNewReading(final String newReading) {
this.newReading = newReading;
}
public String getNewPos() {
return newPos;
}
public void setNewPos(final String newPos) {
this.newPos = newPos;
}
public String getToken() {
return token;
}
public String getSegmentation() {
return segmentation;
}
public String getReading() {
return reading;
}
public String getPos() {
return pos;
}
public boolean isUpdated() {
return newToken != null;
}
public boolean isDeleted() {
return isUpdated() && newToken.length() == 0;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (pos == null ? 0 : pos.hashCode());
result = prime * result + (reading == null ? 0 : reading.hashCode());
result = prime * result
+ (segmentation == null ? 0 : segmentation.hashCode());
result = prime * result + (token == null ? 0 : token.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserDictItem other = (UserDictItem) obj;
if (pos == null) {
if (other.pos != null) {
return false;
}
} else if (!pos.equals(other.pos)) {
return false;
}
if (reading == null) {
if (other.reading != null) {
return false;
}
} else if (!reading.equals(other.reading)) {
return false;
}
if (segmentation == null) {
if (other.segmentation != null) {
return false;
}
} else if (!segmentation.equals(other.segmentation)) {
return false;
}
if (token == null) {
if (other.token != null) {
return false;
}
} else if (!token.equals(other.token)) {
return false;
}
return true;
}
@Override
public String toString() {
return "UserDictItem [token=" + token + ", segmentation="
+ segmentation + ", reading=" + reading + ", pos=" + pos
+ ", newToken=" + newToken + ", newSegmentation="
+ newSegmentation + ", newReading=" + newReading + ", newPos="
+ newPos + "]";
}
public String toLineString() {
final StringBuilder buf = new StringBuilder(100);
if (isUpdated()) {
buf.append(quoteEscape(newToken));
buf.append(',');
buf.append(quoteEscape(newSegmentation));
buf.append(',');
buf.append(quoteEscape(newReading));
buf.append(',');
buf.append(quoteEscape(newPos));
} else {
buf.append(quoteEscape(token));
buf.append(',');
buf.append(quoteEscape(segmentation));
buf.append(',');
buf.append(quoteEscape(reading));
buf.append(',');
buf.append(quoteEscape(pos));
}
return buf.toString();
}
private static String quoteEscape(final String original) {
String result = original;
if (result.indexOf('\"') >= 0) {
result = result.replace("\"", "\"\"");
}
if (result.indexOf(',') >= 0) {
result = "\"" + result + "\"";
}
return result;
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.dict.userdict;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import jp.sf.fess.dict.DictionaryFile;
import jp.sf.fess.dict.DictionaryItem;
import jp.sf.fess.dict.DictionaryLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserDictLocator extends DictionaryLocator {
private static final Logger logger = LoggerFactory
.getLogger(UserDictLocator.class);
public String userDictFilePrefix = "userdict";
public List<String> excludedUserDictList;
@Override
public List<DictionaryFile<? extends DictionaryItem>> find() {
final List<DictionaryFile<? extends DictionaryItem>> fileList = new ArrayList<DictionaryFile<? extends DictionaryItem>>();
for (final String path : searchPathList) {
if (logger.isInfoEnabled()) {
logger.info("UserDict Files from " + path);
}
final File[] files = findFiles(path, userDictFilePrefix,
excludedUserDictList);
for (final File file : files) {
if (logger.isInfoEnabled()) {
logger.info("UserDict File: " + file.getAbsolutePath());
}
fileList.add(new UserDictFile(file));
}
}
Collections.sort(fileList,
new Comparator<DictionaryFile<? extends DictionaryItem>>() {
@Override
public int compare(
final DictionaryFile<? extends DictionaryItem> o1,
final DictionaryFile<? extends DictionaryItem> o2) {
return o1.getName().compareTo(o2.getName());
}
});
return fileList;
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.form.admin.dict;
import java.util.HashMap;
import java.util.Map;
import org.seasar.struts.annotation.IntegerType;
import org.seasar.struts.annotation.LongType;
import org.seasar.struts.annotation.Maxbytelength;
import org.seasar.struts.annotation.Required;
public class UserDictForm {
@IntegerType
public String pageNumber;
public Map<String, String> searchParams = new HashMap<String, String>();
@Required
public String dictId;
@IntegerType
public int crudMode;
public String getCurrentPageNumber() {
return pageNumber;
}
@Required(target = "confirmfromupdate,update,delete")
@LongType
public String id;
@Required(target = "confirmfromcreate,create,confirmfromupdate,update,delete")
@Maxbytelength(maxbytelength = 1000)
public String token;
@Required(target = "confirmfromcreate,create,confirmfromupdate,update,delete")
@Maxbytelength(maxbytelength = 1000)
public String segmentation;
@Required(target = "confirmfromcreate,create,confirmfromupdate,update,delete")
@Maxbytelength(maxbytelength = 1000)
public String reading;
@Required(target = "confirmfromcreate,create,confirmfromupdate,update,delete")
@Maxbytelength(maxbytelength = 1000)
public String pos;
public void initialize() {
id = null;
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.pager;
import java.io.Serializable;
import java.util.List;
public class UserDictPager implements Serializable {
private static final long serialVersionUID = 1L;
private int allRecordCount;
private int allPageCount;
private boolean existPrePage;
private boolean existNextPage;
private List<Integer> pageNumberList;
private int pageSize;
private int currentPageNumber;
public String id;
public void clear() {
pageSize = getDefaultPageSize();
currentPageNumber = getDefaultCurrentPageNumber();
id = null;
}
protected int getDefaultPageSize() {
return 20;
}
protected int getDefaultCurrentPageNumber() {
return 1;
}
public int getAllRecordCount() {
return allRecordCount;
}
public void setAllRecordCount(final int allRecordCount) {
this.allRecordCount = allRecordCount;
}
public int getAllPageCount() {
return allPageCount;
}
public void setAllPageCount(final int allPageCount) {
this.allPageCount = allPageCount;
}
public boolean isExistPrePage() {
return existPrePage;
}
public void setExistPrePage(final boolean existPrePage) {
this.existPrePage = existPrePage;
}
public boolean isExistNextPage() {
return existNextPage;
}
public void setExistNextPage(final boolean existNextPage) {
this.existNextPage = existNextPage;
}
public int getPageSize() {
if (pageSize <= 0) {
pageSize = getDefaultPageSize();
}
return pageSize;
}
public void setPageSize(final int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPageNumber() {
if (currentPageNumber <= 0) {
currentPageNumber = getDefaultCurrentPageNumber();
}
return currentPageNumber;
}
public void setCurrentPageNumber(final int currentPageNumber) {
this.currentPageNumber = currentPageNumber;
}
public List<Integer> getPageNumberList() {
return pageNumberList;
}
public void setPageNumberList(final List<Integer> pageNumberList) {
this.pageNumberList = pageNumberList;
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.service;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import jp.sf.fess.crud.CommonConstants;
import jp.sf.fess.dict.DictionaryFile;
import jp.sf.fess.dict.DictionaryFile.PagingList;
import jp.sf.fess.dict.DictionaryManager;
import jp.sf.fess.dict.userdict.UserDictFile;
import jp.sf.fess.dict.userdict.UserDictItem;
import jp.sf.fess.pager.UserDictPager;
import org.seasar.framework.beans.util.Beans;
import org.seasar.framework.util.StringUtil;
import org.seasar.struts.exception.ActionMessagesException;
public class UserDictService {
@Resource
protected DictionaryManager dictionaryManager;
public List<UserDictItem> getUserDictList(final String dictId,
final UserDictPager userDictPager) {
final UserDictFile userDictFile = getUserDictFile(dictId);
final int pageSize = userDictPager.getPageSize();
final PagingList<UserDictItem> userDictList = userDictFile.selectList(
(userDictPager.getCurrentPageNumber() - 1) * pageSize, pageSize);
// update pager
Beans.copy(userDictList, userDictPager)
.includes(CommonConstants.PAGER_CONVERSION_RULE).execute();
userDictList.setPageRangeSize(5);
userDictPager.setPageNumberList(userDictList.createPageNumberList());
return userDictList;
}
protected UserDictFile getUserDictFile(final String dictId) {
final DictionaryFile<?> dictionaryFile = dictionaryManager
.getDictionaryFile(dictId);
if (dictionaryFile instanceof UserDictFile) {
return (UserDictFile) dictionaryFile;
}
throw new ActionMessagesException("errors.expired_dict_id");
}
public UserDictItem getUserDict(final String dictId,
final Map<String, String> paramMap) {
final UserDictFile userDictFile = getUserDictFile(dictId);
final String idStr = paramMap.get("id");
if (StringUtil.isNotBlank(idStr)) {
try {
final long id = Long.parseLong(idStr);
return userDictFile.get(id);
} catch (final NumberFormatException e) {
// ignore
}
}
return null;
}
public void store(final String dictId, final UserDictItem userDictItem) {
final UserDictFile userDictFile = getUserDictFile(dictId);
if (userDictItem.getId() == 0) {
userDictFile.insert(userDictItem);
} else {
userDictFile.update(userDictItem);
}
}
public void delete(final String dictId, final UserDictItem userDictItem) {
final UserDictFile userDictFile = getUserDictFile(dictId);
userDictFile.delete(userDictItem);
}
}

View file

@ -1365,6 +1365,25 @@ labels.dict_synonym_button_edit=Edit
labels.dict_synonym_button_delete=Delete
labels.dict_synonym_button_update=Update
# userdict
labels.dict_userdict_configuration=UserDict List
labels.dict_userdict_title=UserDict List
labels.dict_userdict_list_link=List
labels.dict_userdict_link_create=Create
labels.dict_userdict_link_update=Update
labels.dict_userdict_link_delete=Delete
labels.dict_userdict_link_confirm=Confirm
labels.dict_userdict_token=Token
labels.dict_userdict_segmentation=Segmentation
labels.dict_userdict_reading=Reading
labels.dict_userdict_pos=POS
labels.dict_userdict_button_create=Create
labels.dict_userdict_button_back=Back
labels.dict_userdict_button_confirm=Confirm
labels.dict_userdict_button_edit=Edit
labels.dict_userdict_button_delete=Delete
labels.dict_userdict_button_update=Update
# CRUD PROPERTIES: BEGIN
errors.crud_invalid_mode=Invalid mode(expected value is {0}, but it's {1}).
errors.crud_failed_to_create_crud_table=Failed to create a new data.

View file

@ -1363,6 +1363,25 @@ labels.dict_synonym_button_edit=\u7de8\u96c6
labels.dict_synonym_button_delete=\u524a\u9664
labels.dict_synonym_button_update=\u66f4\u65b0
# userdict
labels.dict_userdict_configuration=\u30e6\u30fc\u30b6\u30fc\u8f9e\u66f8\u4e00\u89a7
labels.dict_userdict_title=\u30e6\u30fc\u30b6\u30fc\u8f9e\u66f8\u4e00\u89a7
labels.dict_userdict_list_link=\u4e00\u89a7
labels.dict_userdict_link_create=\u4f5c\u6210
labels.dict_userdict_link_update=\u66f4\u65b0
labels.dict_userdict_link_delete=\u524a\u9664
labels.dict_userdict_link_confirm=\u78ba\u8a8d
labels.dict_userdict_token=\u30c8\u30fc\u30af\u30f3
labels.dict_userdict_segmentation=\u5206\u5272
labels.dict_userdict_reading=\u8aad\u307f
labels.dict_userdict_pos=\u54c1\u8a5e
labels.dict_userdict_button_create=\u4f5c\u6210
labels.dict_userdict_button_back=\u623b\u308b
labels.dict_userdict_button_confirm=\u78ba\u8a8d
labels.dict_userdict_button_edit=\u7de8\u96c6
labels.dict_userdict_button_delete=\u524a\u9664
labels.dict_userdict_button_update=\u66f4\u65b0
# CRUD PROPERTIES: BEGIN
errors.crud_invalid_mode=\u30e2\u30fc\u30c9\u304c\u9055\u3044\u307e\u3059\u3002(\u6b63\u3057\u3044\u5024\u306f {0} \u3067\u3059\u304c\u3001\u5165\u529b\u3055\u308c\u305f\u5024\u306f {1} \u306b\u306a\u3063\u3066\u3044\u307e\u3059)
errors.crud_failed_to_create_crud_table=\u30c7\u30fc\u30bf\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002

View file

@ -3,6 +3,9 @@
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component name="dictionaryManager" class="jp.sf.fess.dict.DictionaryManager">
<initMethod name="addLocator">
<arg>userDictLocator</arg>
</initMethod>
<initMethod name="addLocator">
<arg>synonymLocator</arg>
</initMethod>
@ -16,4 +19,12 @@
</initMethod>
</component>
<component name="userDictLocator" class="jp.sf.fess.dict.userdict.UserDictLocator">
<property name="excludedUserDictList">{"data", "txlog",
"lib", "bin", "contrib"}</property>
<initMethod name="addSearchPath">
<arg>"${solr.solr.home}"</arg>
</initMethod>
</component>
</components>

View file

@ -0,0 +1,114 @@
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%><tiles:insert template="/WEB-INF/view/common/admin/layout.jsp"
flush="true">
<tiles:put name="title">
<bean:message key="labels.dict_userdict_configuration" />
</tiles:put>
<tiles:put name="header" value="/WEB-INF/view/common/admin/header.jsp" />
<tiles:put name="footer" value="/WEB-INF/view/common/admin/footer.jsp" />
<tiles:put name="menu" value="/WEB-INF/view/common/admin/menu.jsp" />
<tiles:put name="menuType" value="dict" />
<tiles:put name="headerScript" type="string"></tiles:put>
<tiles:put name="body" type="string">
<h3>
<bean:message key="labels.dict_userdict_title" />
</h3>
<%-- Message: BEGIN --%>
<div>
<html:messages id="msg" message="true">
<div class="alert-message info"><bean:write name="msg" ignore="true" /></div>
</html:messages>
<html:errors />
</div>
<%-- Message: END --%>
<div>
<ul class="pills">
<li><s:link href="../index">
<bean:message key="labels.dict_list_link" />
</s:link></li>
<li><s:link href="index?dictId=${f:u(dictId)}">
<bean:message key="labels.dict_userdict_list_link" />
</s:link></li>
<c:if test="${crudMode == 1}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_create" /></a></li>
</c:if>
<c:if test="${crudMode == 2}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_update" /></a></li>
</c:if>
<c:if test="${crudMode == 3}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_delete" /></a></li>
</c:if>
<c:if test="${crudMode == 4}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_confirm" /></a></li>
</c:if>
</ul>
</div>
<%-- Confirm Form: BEGIN --%>
<s:form>
<html:hidden property="crudMode" />
<div>
<html:hidden property="dictId" />
<c:if test="${crudMode==2 || crudMode==3 || crudMode==4}">
<html:hidden property="id" />
</c:if>
<table class="bordered-table zebra-striped" style="width: 500px;">
<tbody>
<tr>
<th style="width: 150px;"><bean:message
key="labels.dict_userdict_token" /></th>
<td>${f:h(token)}<html:hidden property="token" /></td>
</tr>
<tr>
<th><bean:message key="labels.dict_userdict_segmentation" /></th>
<td>${f:h(segmentation)}<html:hidden property="segmentation" /></td>
</tr>
<tr>
<th><bean:message key="labels.dict_userdict_reading" /></th>
<td>${f:h(reading)}<html:hidden property="reading" /></td>
</tr>
<tr>
<th><bean:message key="labels.dict_userdict_pos" /></th>
<td>${f:h(pos)}<html:hidden property="pos" /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2"><c:if test="${crudMode == 1}">
<input type="submit" class="btn mini" name="create"
value="<bean:message key="labels.dict_userdict_button_create"/>" />
<input type="submit" class="btn mini" name="editagain"
value="<bean:message key="labels.dict_userdict_button_back"/>" />
</c:if> <c:if test="${crudMode == 2}">
<input type="submit" class="btn mini" name="update"
value="<bean:message key="labels.dict_userdict_button_update"/>" />
<input type="submit" class="btn mini" name="editagain"
value="<bean:message key="labels.dict_userdict_button_back"/>" />
</c:if> <c:if test="${crudMode == 3}">
<input type="submit" class="btn mini" name="delete"
value="<bean:message key="labels.dict_userdict_button_delete"/>" />
<input type="submit" class="btn mini" name="back"
value="<bean:message key="labels.dict_userdict_button_back"/>" />
</c:if> <c:if test="${crudMode == 4}">
<input type="submit" class="btn mini" name="back"
value="<bean:message key="labels.dict_userdict_button_back"/>" />
<input type="submit" class="btn mini" name="editfromconfirm"
value="<bean:message key="labels.dict_userdict_button_edit"/>" />
<input type="submit" class="btn mini" name="deletefromconfirm"
value="<bean:message key="labels.dict_userdict_button_delete"/>" />
</c:if></td>
</tr>
</tfoot>
</table>
</div>
</s:form>
<%-- Confirm Form: BEGIN --%>
</tiles:put>
</tiles:insert>

View file

@ -0,0 +1,105 @@
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%><tiles:insert template="/WEB-INF/view/common/admin/layout.jsp"
flush="true">
<tiles:put name="title">
<bean:message key="labels.dict_userdict_configuration" />
</tiles:put>
<tiles:put name="header" value="/WEB-INF/view/common/admin/header.jsp" />
<tiles:put name="footer" value="/WEB-INF/view/common/admin/footer.jsp" />
<tiles:put name="menu" value="/WEB-INF/view/common/admin/menu.jsp" />
<tiles:put name="menuType" value="dict" />
<tiles:put name="headerScript" type="string"></tiles:put>
<tiles:put name="body" type="string">
<h3>
<bean:message key="labels.dict_userdict_title" />
</h3>
<%-- Message: BEGIN --%>
<div>
<html:messages id="msg" message="true">
<div class="alert-message info"><bean:write name="msg" ignore="true" /></div>
</html:messages>
<html:errors />
</div>
<%-- Message: END --%>
<div>
<ul class="pills">
<li><s:link href="../index">
<bean:message key="labels.dict_list_link" />
</s:link></li>
<li><s:link href="index?dictId=${f:u(dictId)}">
<bean:message key="labels.dict_userdict_list_link" />
</s:link></li>
<c:if test="${crudMode == 1}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_create" /></a></li>
</c:if>
<c:if test="${crudMode == 2}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_update" /></a></li>
</c:if>
<c:if test="${crudMode == 3}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_delete" /></a></li>
</c:if>
<c:if test="${crudMode == 4}">
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_link_confirm" /></a></li>
</c:if>
</ul>
</div>
<%-- Edit Form: BEGIN --%>
<s:form>
<html:hidden property="crudMode" />
<div>
<html:hidden property="dictId" />
<c:if test="${crudMode==2}">
<html:hidden property="id" />
</c:if>
<table class="bordered-table zebra-striped" style="width: 500px;">
<tbody>
<tr>
<th style="width: 150px;"><bean:message
key="labels.dict_userdict_token" /></th>
<td><html:text property="token" style="width:98%;" /></td>
</tr>
<tr>
<th><bean:message
key="labels.dict_userdict_segmentation" /></th>
<td><html:text property="segmentation" style="width:98%;" /></td>
</tr>
<tr>
<th><bean:message
key="labels.dict_userdict_reading" /></th>
<td><html:text property="reading" style="width:98%;" /></td>
</tr>
<tr>
<th><bean:message
key="labels.dict_userdict_pos" /></th>
<td><html:text property="pos" style="width:98%;" /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2"><c:if test="${crudMode == 1}">
<input type="submit" class="btn mini" name="confirmfromcreate"
value="<bean:message key="labels.dict_userdict_button_create"/>" />
<input type="submit" class="btn mini" name="back"
value="<bean:message key="labels.dict_userdict_button_back"/>" />
</c:if> <c:if test="${crudMode == 2}">
<input type="submit" class="btn mini" name="confirmfromupdate"
value="<bean:message key="labels.dict_userdict_button_confirm"/>" />
<input type="submit" class="btn mini" name="back"
value="<bean:message key="labels.dict_userdict_button_back"/>" />
</c:if></td>
</tr>
</tfoot>
</table>
</div>
</s:form>
<%-- Edit Form: BEGIN --%>
</tiles:put>
</tiles:insert>

View file

@ -0,0 +1,19 @@
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%><tiles:insert template="/WEB-INF/view/common/admin/layout.jsp" flush="true">
<tiles:put name="title"><bean:message key="labels.dict_userdict_configuration" /></tiles:put>
<tiles:put name="header" value="/WEB-INF/view/common/admin/header.jsp" />
<tiles:put name="footer" value="/WEB-INF/view/common/admin/footer.jsp" />
<tiles:put name="menu" value="/WEB-INF/view/common/admin/menu.jsp" />
<tiles:put name="menuType" value="dict" />
<tiles:put name="headerScript" type="string"></tiles:put>
<tiles:put name="body" type="string">
<div id="main">
<html:errors/>
<br/>
<s:link href="../index"><bean:message key="labels.dict_button_back"/></s:link>
</div>
</tiles:put>
</tiles:insert>

View file

@ -0,0 +1,121 @@
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%><tiles:insert template="/WEB-INF/view/common/admin/layout.jsp"
flush="true">
<tiles:put name="title">
<bean:message key="labels.dict_userdict_configuration" />
</tiles:put>
<tiles:put name="header" value="/WEB-INF/view/common/admin/header.jsp" />
<tiles:put name="footer" value="/WEB-INF/view/common/admin/footer.jsp" />
<tiles:put name="menu" value="/WEB-INF/view/common/admin/menu.jsp" />
<tiles:put name="menuType" value="dict" />
<tiles:put name="headerScript" type="string"></tiles:put>
<tiles:put name="body" type="string">
<h3>
<bean:message key="labels.dict_userdict_title" />
</h3>
<%-- Message: BEGIN --%>
<div>
<html:messages id="msg" message="true">
<div class="alert-message info"><bean:write name="msg" ignore="true" /></div>
</html:messages>
<html:errors />
</div>
<%-- Message: END --%>
<%-- List: BEGIN --%>
<div class="list-table">
<div>
<ul class="pills">
<li><s:link href="../index">
<bean:message key="labels.dict_list_link" />
</s:link></li>
<li class="active"><a href="#"><bean:message
key="labels.dict_userdict_list_link" /></a></li>
<li><s:link href="createpage?dictId=${f:u(dictId)}">
<bean:message key="labels.dict_userdict_link_create" />
</s:link></li>
</ul>
</div>
<c:if test="${userDictPager.allRecordCount == 0}">
<p class="alert-message warning">
<bean:message key="labels.list_could_not_find_crud_table" />
</p>
</c:if>
<c:if test="${userDictPager.allRecordCount > 0}">
<table class="bordered-table zebra-striped">
<thead>
<tr>
<th style="text-align: left;"><bean:message
key="labels.dict_userdict_token" /></th>
<th style="text-align: left;"><bean:message
key="labels.dict_userdict_reading" /></th>
<th style="text-align: center; width: 200px;">&nbsp;</th>
</tr>
</thead>
<tbody>
<c:forEach var="data" varStatus="s" items="${userDictItemItems}">
<tr class="${s.index % 2 == 0 ? 'row1' : 'row2'}">
<td>${f:h(data.token)}</td>
<td>${f:h(data.reading)}</td>
<td style="text-align: center;"><s:link
href="confirmpage/${f:u(dictId)}/4/${f:u(data.id)}">
<bean:message key="labels.dict_link_details" />
</s:link> <s:link href="editpage/${f:u(dictId)}/2/${f:u(data.id)}">
<bean:message key="labels.dict_link_edit" />
</s:link> <s:link href="deletepage/${f:u(dictId)}/3/${f:u(data.id)}">
<bean:message key="labels.dict_link_delete" />
</s:link></td>
</tr>
</c:forEach>
</tbody>
</table>
<%-- Page Navigation: BEGIN --%>
<div class="row center">
<div class="pagination">
<ul>
<c:if test="${userDictPager.existPrePage}">
<li class="prev"><s:link
href="list/${f:u(dictId)}/${userDictPager.currentPageNumber - 1}">
<bean:message key="labels.dict_link_prev_page" />
</s:link></li>
</c:if>
<c:if test="${!userDictPager.existPrePage}">
<li class="prev disabled"><a href="#"><bean:message
key="labels.dict_link_prev_page" /></a></li>
</c:if>
<c:forEach var="p" varStatus="s"
items="${userDictPager.pageNumberList}">
<li
<c:if test="${p == userDictPager.currentPageNumber}">class="active"</c:if>>
<s:link href="list/${f:u(dictId)}/${p}">${p}</s:link>
</li>
</c:forEach>
<c:if test="${userDictPager.existNextPage}">
<li class="next disabled"><s:link
href="list/${f:u(dictId)}/${userDictPager.currentPageNumber + 1}">
<bean:message key="labels.dict_link_next_page" />
</s:link></li>
</c:if>
<c:if test="${!userDictPager.existNextPage}">
<li class="next disabled"><a href="#"><bean:message
key="labels.dict_link_next_page" /></a></li>
</c:if>
</ul>
</div>
<div>
<span><bean:message key="labels.pagination_page_guide_msg"
arg0="${f:h(userDictPager.currentPageNumber)}"
arg1="${f:h(userDictPager.allPageCount)}"
arg2="${f:h(userDictPager.allRecordCount)}" /></span>
</div>
</div>
<%-- Page Navigation: END --%>
</c:if>
</div>
<%-- List: END --%>
</tiles:put>
</tiles:insert>

View file

@ -0,0 +1,169 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.dict.userdict;
import java.io.File;
import jp.sf.fess.Constants;
import jp.sf.fess.dict.DictionaryFile.PagingList;
import org.seasar.extension.unit.S2TestCase;
import org.seasar.framework.util.FileUtil;
public class UserDictFileTest extends S2TestCase {
private File file1;
@Override
protected void setUp() throws Exception {
file1 = File.createTempFile("userdict_", ".txt");
FileUtil.write(
file1.getAbsolutePath(),
"token1,seg1,reading1,pos1\ntoken2,seg2,reading2,pos2\ntoken3,seg3,reading3,pos3"
.getBytes(Constants.UTF_8));
}
@Override
protected void tearDown() throws Exception {
file1.delete();
}
public void test_selectList() {
final UserDictFile userDictFile = new UserDictFile(file1);
final PagingList<UserDictItem> itemList1 = userDictFile.selectList(0,
20);
assertEquals(3, itemList1.size());
assertEquals(3, itemList1.getAllRecordCount());
assertEquals(1, itemList1.getCurrentPageNumber());
assertEquals(20, itemList1.getPageSize());
final PagingList<UserDictItem> itemList2 = userDictFile
.selectList(2, 2);
assertEquals(1, itemList2.size());
assertEquals(3, itemList2.getAllRecordCount());
assertEquals(2, itemList2.getCurrentPageNumber());
assertEquals(2, itemList2.getPageSize());
assertEquals(0, userDictFile.selectList(5, 5).size());
assertEquals(0, userDictFile.selectList(-1, 5).size());
}
public void test_selectList2() {
final UserDictFile userDictFile = new UserDictFile(file1);
final PagingList<UserDictItem> itemList = userDictFile.selectList(0, 5);
for (int i = 0; i < itemList.size(); i++) {
final UserDictItem userDictItem = itemList.get(i);
assertEquals("token" + (i + 1), userDictItem.getToken());
assertEquals("seg" + (i + 1), userDictItem.getSegmentation());
assertEquals("reading" + (i + 1), userDictItem.getReading());
assertEquals("pos" + (i + 1), userDictItem.getPos());
assertFalse(userDictItem.isUpdated());
assertFalse(userDictItem.isUpdated());
}
}
public void test_insert() {
final UserDictFile userDictFile = new UserDictFile(file1);
final PagingList<UserDictItem> itemList1 = userDictFile.selectList(0,
20);
assertEquals(3, itemList1.size());
final UserDictItem userDictItem1 = new UserDictItem(0, "token4",
"seg4", "reading4", "pos4");
userDictFile.insert(userDictItem1);
final PagingList<UserDictItem> itemList2 = userDictFile.selectList(0,
20);
assertEquals(4, itemList2.size());
assertEquals("token4", itemList2.get(3).getToken());
assertEquals("seg4", itemList2.get(3).getSegmentation());
assertEquals("reading4", itemList2.get(3).getReading());
assertEquals("pos4", itemList2.get(3).getPos());
final UserDictItem userDictItem2 = new UserDictItem(0, "token5",
"seg5", "reading5", "pos5");
userDictFile.insert(userDictItem2);
final PagingList<UserDictItem> itemList3 = userDictFile.selectList(0,
20);
assertEquals(5, itemList3.size());
assertEquals("token5", itemList3.get(4).getToken());
assertEquals("seg5", itemList3.get(4).getSegmentation());
assertEquals("reading5", itemList3.get(4).getReading());
assertEquals("pos5", itemList3.get(4).getPos());
}
public void test_update() {
final UserDictFile userDictFile = new UserDictFile(file1);
final PagingList<UserDictItem> itemList1 = userDictFile.selectList(0,
20);
assertEquals(3, itemList1.size());
final UserDictItem userDictItem1 = itemList1.get(0);
userDictItem1.setNewToken("TOKEN1");
userDictItem1.setNewSegmentation("SEG1");
userDictItem1.setNewReading("READING1");
userDictItem1.setNewPos("POS1");
userDictFile.update(userDictItem1);
final PagingList<UserDictItem> itemList2 = userDictFile.selectList(0,
20);
assertEquals(3, itemList2.size());
final UserDictItem userDictItem2 = itemList2.get(0);
assertEquals("TOKEN1", userDictItem2.getToken());
assertEquals("SEG1", userDictItem2.getSegmentation());
assertEquals("READING1", userDictItem2.getReading());
assertEquals("POS1", userDictItem2.getPos());
assertFalse(userDictItem2.isUpdated());
final UserDictItem userDictItem3 = itemList2.get(2);
userDictItem3.setNewToken("TOKEN3");
userDictItem3.setNewSegmentation("SEG3");
userDictItem3.setNewReading("READING3");
userDictItem3.setNewPos("POS3");
userDictFile.update(userDictItem3);
final PagingList<UserDictItem> itemList3 = userDictFile.selectList(0,
20);
assertEquals(3, itemList3.size());
final UserDictItem userDictItem4 = itemList3.get(2);
assertEquals("TOKEN3", userDictItem4.getToken());
assertEquals("SEG3", userDictItem4.getSegmentation());
assertEquals("READING3", userDictItem4.getReading());
assertEquals("POS3", userDictItem4.getPos());
assertFalse(userDictItem4.isUpdated());
}
public void test_delete() throws Exception {
final UserDictFile userDictFile = new UserDictFile(file1);
final PagingList<UserDictItem> itemList1 = userDictFile.selectList(0,
20);
assertEquals(3, itemList1.size());
final UserDictItem userDictItem1 = itemList1.get(0);
userDictFile.delete(userDictItem1);
final PagingList<UserDictItem> itemList2 = userDictFile.selectList(0,
20);
assertEquals(2, itemList2.size());
final UserDictItem userDictItem2 = itemList2.get(1);
userDictFile.delete(userDictItem2);
final PagingList<UserDictItem> itemList3 = userDictFile.selectList(0,
20);
assertEquals(1, itemList3.size());
assertEquals("token2,seg2,reading2,pos2" + Constants.LINE_SEPARATOR,
new String(FileUtil.getBytes(file1), Constants.UTF_8));
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.dict.userdict;
import org.seasar.extension.unit.S2TestCase;
public class UserDictItemTest extends S2TestCase {
public void test_new1() {
final UserDictItem userDictItem = new UserDictItem(1, "t1", "s1", "r1",
"p1");
assertEquals(1, userDictItem.getId());
assertEquals("t1", userDictItem.getToken());
assertEquals("s1", userDictItem.getSegmentation());
assertEquals("r1", userDictItem.getReading());
assertEquals("p1", userDictItem.getPos());
assertNull(userDictItem.getNewToken());
assertNull(userDictItem.getNewSegmentation());
assertNull(userDictItem.getNewReading());
assertNull(userDictItem.getNewPos());
assertFalse(userDictItem.isUpdated());
assertFalse(userDictItem.isDeleted());
userDictItem.setNewToken("T1");
userDictItem.setNewSegmentation("S1");
userDictItem.setNewReading("R1");
userDictItem.setNewPos("P1");
assertTrue(userDictItem.isUpdated());
assertFalse(userDictItem.isDeleted());
userDictItem.setNewToken("");
assertTrue(userDictItem.isUpdated());
assertTrue(userDictItem.isDeleted());
}
public void test_equals1() {
final UserDictItem userDictItem1 = new UserDictItem(1, "t1", "s1",
"r1", "p1");
assertTrue(userDictItem1.equals(userDictItem1));
assertTrue(userDictItem1.equals(new UserDictItem(1, "t1", "s1", "r1",
"p1")));
assertTrue(userDictItem1.equals(new UserDictItem(2, "t1", "s1", "r1",
"p1")));
assertFalse(userDictItem1.equals(new UserDictItem(1, "T1", "s1", "r1",
"p1")));
assertFalse(userDictItem1.equals(new UserDictItem(1, "t1", "S1", "r1",
"p1")));
assertFalse(userDictItem1.equals(new UserDictItem(1, "t1", "s1", "R1",
"p1")));
assertFalse(userDictItem1.equals(new UserDictItem(1, "t1", "s1", "r1",
"P1")));
}
public void test_toLineString() {
assertEquals("t1,s1,r1,p1",
new UserDictItem(1, "t1", "s1", "r1", "p1").toLineString());
assertEquals("t\"\"1,s\"\"1,r\"\"1,p\"\"1", new UserDictItem(1, "t\"1",
"s\"1", "r\"1", "p\"1").toLineString());
assertEquals("\"t,1\",\"s,1\",\"r,1\",\"p,1\"", new UserDictItem(1,
"t,1", "s,1", "r,1", "p,1").toLineString());
assertEquals("\"t\"\",1\",\"s\"\",1\",\"r\"\",1\",\"p\"\",1\"",
new UserDictItem(1, "t\",1", "s\",1", "r\",1", "p\",1")
.toLineString());
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright 2009-2014 the CodeLibs Project and the Others.
*
* Licensed 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.
*/
package jp.sf.fess.dict.userdict;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import jp.sf.fess.Constants;
import jp.sf.fess.dict.DictionaryFile;
import jp.sf.fess.dict.DictionaryItem;
import org.apache.commons.io.FileUtils;
import org.seasar.extension.unit.S2TestCase;
import org.seasar.framework.util.FileUtil;
public class UserDictLocatorTest extends S2TestCase {
private File testDir;
private File testDataDir;
private File testCoreDir;
private File userDictFile1;
private File userDictFile2;
private File userDictFile3;
private File dummyFile1;
private File dummyFile2;
@Override
protected void setUp() throws Exception {
testDir = File.createTempFile("userdicttest", "_dir");
testDir.delete();
testDir.mkdirs();
testDataDir = new File(testDir, "data");
testDataDir.mkdirs();
testCoreDir = new File(testDir, "core");
testCoreDir.mkdirs();
userDictFile1 = new File(testDir, "userdict.txt");
FileUtil.write(userDictFile1.getAbsolutePath(),
"abc=>123\nxyz,890".getBytes(Constants.UTF_8));
userDictFile2 = new File(testDataDir, "userdict_data.txt");
FileUtil.write(userDictFile2.getAbsolutePath(),
"abc=>123\nxyz,890".getBytes(Constants.UTF_8));
userDictFile3 = new File(testCoreDir, "userdict_core.txt");
FileUtil.write(userDictFile3.getAbsolutePath(),
"abc=>123\nxyz,890".getBytes(Constants.UTF_8));
dummyFile1 = new File(testDir, "dummy.txt");
FileUtil.write(dummyFile1.getAbsolutePath(),
"dummy 1".getBytes(Constants.UTF_8));
dummyFile2 = new File(testCoreDir, "dummy.txt");
FileUtil.write(dummyFile2.getAbsolutePath(),
"dummy 2".getBytes(Constants.UTF_8));
}
@Override
protected void tearDown() throws Exception {
FileUtils.deleteDirectory(testDir);
}
public void test_find() {
final UserDictLocator userDictLocator = new UserDictLocator();
userDictLocator.excludedUserDictList = new ArrayList<String>();
userDictLocator.excludedUserDictList.add("data");
userDictLocator.addSearchPath(testDir.getAbsolutePath());
final List<DictionaryFile<? extends DictionaryItem>> list = userDictLocator
.find();
assertEquals(2, list.size());
final DictionaryFile<? extends DictionaryItem> dicFile1 = list.get(0);
final DictionaryFile<? extends DictionaryItem> dicFile2 = list.get(1);
assertEquals(userDictFile3.getAbsolutePath(), dicFile1.getName());
assertEquals(userDictFile1.getAbsolutePath(), dicFile2.getName());
}
}