package com.psddev.cms.tool.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.psddev.cms.db.Draft;
import com.psddev.cms.tool.CmsTool;
import com.psddev.cms.tool.Search;
import com.psddev.cms.tool.SearchResultAction;
import com.psddev.cms.tool.SearchResultSelection;
import com.psddev.cms.tool.SearchResultSelectionItem;
import com.psddev.cms.tool.SearchResultSelectionGeneratable;
import com.psddev.cms.tool.ToolPageContext;
import com.psddev.cms.tool.page.CreateDraft;
import com.psddev.dari.db.Database;
import com.psddev.dari.db.ObjectField;
import com.psddev.dari.db.ObjectType;
import com.psddev.dari.db.Query;
import com.psddev.dari.db.State;
import com.psddev.dari.util.UrlBuilder;
public class CreateDraftSearchResultAction implements SearchResultAction {
@Override
public int getPosition() {
return -1;
}
@Override
public void writeHtml(
ToolPageContext page,
Search search,
SearchResultSelection selection)
throws IOException {
if (selection == null) {
return;
}
Query<SearchResultSelectionItem> itemsQuery = Query
.from(SearchResultSelectionItem.class)
.where("selectionId = ?", selection.getId());
if (!itemsQuery.hasMoreThan(100)) {
Set<ObjectType> itemTypes = new HashSet<>();
for (Object item : selection.createItemsQuery()
.selectAll()) {
itemTypes.add(State.getInstance(item).getType());
}
List<TypeAndItemTypes> generates = new ArrayList<>();
for (ObjectType type : Database.Static.getDefault().getEnvironment().getTypes()) {
if (!type.isConcrete()
|| !page.hasPermission("type/" + type.getId() + "/write")
|| (!page.getCmsTool().isDisplayTypesNotAssociatedWithJavaClasses()
&& type.getObjectClass() == null)
|| Draft.class.equals(type.getObjectClass())
|| (type.isDeprecated()
&& !Query.fromType(type).hasMoreThan(0))) {
continue;
}
Set<ObjectType> generatableItemTypes = new HashSet<>();
for (ObjectType itemType : type.as(SearchResultSelectionGeneratable.TypeData.class).getItemTypes()) {
generatableItemTypes.addAll(itemType.findConcreteTypes());
}
if (type.getObjectClass() != null
&& type.getGroups().contains(SearchResultSelectionGeneratable.class.getName())
&& generatableItemTypes.containsAll(itemTypes)) {
generates.add(new TypeAndItemTypes(type, new ArrayList<>(itemTypes)));
}
}
if (!generates.isEmpty()) {
Collections.sort(generates);
for (TypeAndItemTypes generate : generates) {
page.writeStart("div", "class", "searchResult-action-simple");
page.writeStart("a",
"class", "button",
"target", "_top",
"href", new UrlBuilder(page.getRequest())
.absolutePath(page.toolPath(CmsTool.class, CreateDraft.PATH))
.currentParameters()
.parameter("typeIdAndField", generate.type.getId())
.parameter("selectionId", selection.getId()));
page.writeHtml(page.localize(CreateDraftSearchResultAction.class, "action.createNew"));
page.writeHtml(" ");
page.writeObjectLabel(generate.type);
page.writeEnd(); // end a.button
page.writeEnd(); // end div.searchResult-action-simple
}
}
}
}
private static class TypeAndItemTypes implements Comparable<TypeAndItemTypes> {
public final ObjectType type;
public final List<ObjectType> componentTypes;
public TypeAndItemTypes(ObjectType type, List<ObjectType> componentTypes) {
this.type = type;
this.componentTypes = componentTypes;
}
@Override
public int compareTo(TypeAndItemTypes other) {
int typeCompare = type.compareTo(other.type);
int componentSizeCompare = (componentTypes.size() > other.componentTypes.size()) ? 1 : ((componentTypes.size() < other.componentTypes.size()) ? -1 : 0);
return typeCompare != 0 ? typeCompare : componentSizeCompare;
}
}
private static class TypeAndField implements Comparable<TypeAndField> {
public final ObjectType type;
public final ObjectField field;
public TypeAndField(ObjectType type, ObjectField field) {
this.type = type;
this.field = field;
}
@Override
public int compareTo(TypeAndField other) {
int typeCompare = type.compareTo(other.type);
return typeCompare != 0 ? typeCompare : field.compareTo(other.field);
}
}
}