package marubinotto.piggydb.ui.page.partial;
import static marubinotto.util.CollectionUtils.list;
import static marubinotto.util.web.WebUtils.escapeHtml;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import marubinotto.piggydb.model.Classification;
import marubinotto.piggydb.model.Filter;
import marubinotto.piggydb.model.Fragment;
import marubinotto.piggydb.model.Tag;
import marubinotto.piggydb.model.entity.RawFilter;
import marubinotto.piggydb.model.query.FragmentsAllButTrash;
import marubinotto.piggydb.model.query.FragmentsQuery;
import marubinotto.piggydb.model.query.FragmentsSortOption;
import marubinotto.piggydb.ui.wiki.DefaultWikiParser;
import marubinotto.piggydb.util.PiggydbUtils;
import marubinotto.util.RegexUtils;
import marubinotto.util.paging.Page;
import marubinotto.util.paging.PageUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
public abstract class AbstractFragments extends AbstractPartial {
//
// Input
//
public String viewId;
public Integer scale; // 0 - 1000
public Integer orderBy;
public Boolean ascending;
public Boolean shuffle;
private FragmentsSortOption sortOption;
public int pi = 0;
public static final String SK_SCALE = "fragmentsViewScale";
public static final String SK_ORDERBY = "fragmentsViewOrderBy";
public static final String SK_ASCENDING = "fragmentsViewAscending";
public String query;
public String tagsToInclude;
public Boolean tagsToIncludeAnd;
public String tagsToExclude;
@Override
public void onInit() {
super.onInit();
// restore the session values
if (this.scale == null) {
this.scale = (Integer)ObjectUtils.defaultIfNull(
getContext().getSessionAttribute(SK_SCALE),
getWarSetting().getDefaultFragmentsViewScale());
}
if (this.orderBy == null) {
this.orderBy = (Integer)getContext().getSessionAttribute(SK_ORDERBY);
}
if (this.ascending == null) {
this.ascending = (Boolean)getContext().getSessionAttribute(SK_ASCENDING);
}
// create a sortOption
this.sortOption = new FragmentsSortOption(this.orderBy, this.ascending);
if (this.shuffle != null) {
this.sortOption.shuffle = this.shuffle;
}
if (isNotBlank(this.query)) {
this.query = modifyIfGarbledByTomcat(this.query);
}
}
//
// Model
//
public FragmentsView view;
public String label = "";
public boolean hideHeader = false;
public Page<Fragment> fragments;
public Classification contextTags;
public boolean firstSet = true;
public boolean lastSet = false;
public String keywordRegex;
public Filter filter;
@Override
protected void setModels() throws Exception {
super.setModels();
this.view = new FragmentsView(this.viewId);
this.view.setScale(this.scale);
setSelectedFragments();
checkFragmentRef();
this.filter = createFilter();
if (this.fragments == null) setFragmentsByFilter();
if (this.fragments == null) setFragments();
if (this.fragments != null) {
this.firstSet = (this.pi == 0);
this.lastSet = this.fragments.isLastPage();
}
saveStateToSession();
}
private void checkFragmentRef() throws Exception {
if (isBlank(this.query)) return;
// query == "#<number>"
if (this.query.matches(DefaultWikiParser.PS_FRAGMENT_REF)) {
long id = Long.parseLong(this.query.substring(1));
Fragment fragment = getDomain().getFragmentRepository().get(id);
this.fragments = fragment != null ?
PageUtils.getPage(list(fragment), this.view.getPageSize(), this.pi) :
emptyFragments();
this.label = this.query;
}
}
private Page<Fragment> emptyFragments() {
return PageUtils.<Fragment>empty(this.view.getPageSize());
}
protected Filter createFilter() throws Exception {
return null;
}
private void setFragmentsByFilter() throws Exception {
if (this.filter == null) return;
// add tags to include
if (isNotBlank(this.tagsToInclude)) {
this.tagsToInclude = modifyIfGarbledByTomcat(this.tagsToInclude);
for (String tagName : StringUtils.split(this.tagsToInclude, ',')) {
Tag tag = getTagByName(tagName);
if (tag == null) {
this.fragments = emptyFragments();
continue;
}
((RawFilter)this.filter).getIncludes().addTag(tag);
}
if (this.tagsToIncludeAnd != null) {
((RawFilter)this.filter).setAnd(this.tagsToIncludeAnd);
}
}
this.contextTags = this.filter.getIncludes();
// add tag to exclude
if (isNotBlank(this.tagsToExclude)) {
this.tagsToExclude = modifyIfGarbledByTomcat(this.tagsToExclude);
for (String tagName : StringUtils.split(this.tagsToExclude, ',')) {
Tag tag = getTagByName(tagName);
if (tag != null) {
((RawFilter)this.filter).getExcludes().addTag(tag);
}
}
}
if (this.fragments != null) return;
// query
if (this.filter.isEmpty() && isBlank(this.query)) {
this.label = getMessage("all");
FragmentsQuery query = getQuery(FragmentsAllButTrash.class);
this.fragments = getPage(query);
if (this.fragments.getTotalSize() == 0 && isBlank(this.query)) {
this.hideHeader = true;
}
}
else {
appendFilterLabel(this.filter);
marubinotto.piggydb.model.query.FragmentsByFilter query =
(marubinotto.piggydb.model.query.FragmentsByFilter)getQuery(
marubinotto.piggydb.model.query.FragmentsByFilter.class);
query.setFilter(this.filter);
if (isNotBlank(this.query)) {
query.setKeywords(this.query);
setKeywordRegex(this.query);
appendKeywordSearchLabel();
}
this.fragments = getPage(query);
}
}
private Tag getTagByName(String name) throws Exception {
return isNotBlank(name) ? getDomain().getTagRepository().getByName(name.trim()) : null;
}
protected void setKeywordRegex(String keywords) {
StringBuilder keywordRegex = new StringBuilder();
for (String word : PiggydbUtils.splitToKeywords(keywords)) {
if (keywordRegex.length() > 0) keywordRegex.append("|");
word = StringEscapeUtils.escapeJavaScript(word);
word = RegexUtils.escapeRegex(word);
keywordRegex.append(word);
}
this.keywordRegex = "(" + keywordRegex.toString() + ")";
}
protected FragmentsQuery getQuery(Class<? extends FragmentsQuery> queryClass)
throws Exception {
FragmentsQuery query = (FragmentsQuery)
getDomain().getFragmentRepository().getQuery(queryClass);
query.setSortOption(this.sortOption);
query.setEagerFetching(this.view.needsEagerFetching());
query.setEagerFetchingMore(this.view.needsEagerFetchingMore());
return query;
}
protected Page<Fragment> getPage(FragmentsQuery query) throws Exception {
return query.getPage(this.view.getPageSize(), this.pi);
}
protected void setFragments() throws Exception {
}
private void saveStateToSession() {
if (this.scale != null) getContext().setSessionAttribute(SK_SCALE, this.scale);
if (this.orderBy != null) getContext().setSessionAttribute(SK_ORDERBY, this.orderBy);
if (this.ascending != null) getContext().setSessionAttribute(SK_ASCENDING, this.ascending);
}
protected static String makeKeywordSearchLabel(String keywords) {
String label = "<span class=\"search-icon-mini\"> </span> ";
for (String keyword : PiggydbUtils.splitToKeywords(keywords)) {
label += "\"" + keyword + "\" ";
}
return label.trim();
}
protected void appendKeywordSearchLabel() {
if (isBlank(this.query)) return;
if (isNotBlank(this.label)) {
this.label += " + ";
}
this.label += makeKeywordSearchLabel(this.query);
}
private String makeTagLabel(String tagName) {
return "<span class=\"" + this.html.miniTagIconClass(tagName) +
"\"> </span> " + escapeHtml(tagName);
}
protected void appendFilterLabel(Filter filter) {
String separator = filter.isAnd() ? " & " : " | ";
separator = "<span class=\"tag-separator\">" + separator + "</span>";
boolean first = true;
for (Tag tag : filter.getIncludes()) {
if (first) {
first = false;
}
else {
this.label += separator;
}
this.label += makeTagLabel(tag.getName());
}
}
}