changeset 174:4961820373d0

Merge from public_by_author aa564b1b5e1f28b00de5c639ccd9abd2e6299323
author Robert Casties <casties@mpiwg-berlin.mpg.de>
date Wed, 06 Jun 2018 21:02:30 +0200
parents caf1aa768457 (current diff) aa564b1b5e1f (diff)
children 3d8b31508128
files
diffstat 13 files changed, 811 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/de/mpiwg/itgroup/ismi/browse/AbstractEntityRepositoryBean.java	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/java/de/mpiwg/itgroup/ismi/browse/AbstractEntityRepositoryBean.java	Wed Jun 06 21:02:30 2018 +0200
@@ -22,57 +22,58 @@
 
 	private static final long serialVersionUID = 3154642100627969159L;
 
-	private static Logger logger = Logger.getLogger(AbstractEntityRepositoryBean.class);
+	protected static Logger logger = Logger.getLogger(AbstractEntityRepositoryBean.class);
 	
 	public static String MODE_ADVANCED = "advanced";
 	public static String MODE_ALL = "all";
 	public static String MODE_NONE = "none";
 	
 
-	private String objectClass = null;
-	private List<Entity> entities = new ArrayList<Entity>();
-	private List<Entity> currentEntities = new ArrayList<Entity>();
+	protected String objectClass = null;
+	protected List<Entity> entities = new ArrayList<Entity>();
+	protected List<Entity> currentEntities = new ArrayList<Entity>();
 
-	private List<SelectItem> definitions = new ArrayList<SelectItem>();
+	protected List<SelectItem> definitions = new ArrayList<SelectItem>();
 	
-	private transient DataPaginator advancedPaginator = new DataPaginator();
+	protected transient DataPaginator advancedPaginator = new DataPaginator();
 
-	private String ocTerm;
-	private String currentTab;
+	protected String ocTerm;
+	protected String currentTab;
 	
-	private String textFullTitle;
-	private String textFullTitleTranslit;
-	private String textShortTitle;
+	protected String textFullTitle;
+	protected String textFullTitleTranslit;
+	protected String textShortTitle;
 
-	private String personName;
-	private String personNameTranslit;
+	protected String personName;
+	protected String personNameTranslit;
+	protected String personMamsNr;
 
-	private String codexIdentifier;
+	protected String codexIdentifier;
 	
-	private String collectionName;
+	protected String collectionName;
 
-	private String placeName;
-	private String placeType;
+	protected String placeName;
+	protected String placeType;
 	
-	private String aliasAlias;
+	protected String aliasAlias;
 	
-	private String repositoryName;
+	protected String repositoryName;
 	
-	private String witnessFullTitle;
-	private String witnessFullTitleTranslit;
-	private String witnessAhlwardtNo;
+	protected String witnessFullTitle;
+	protected String witnessFullTitleTranslit;
+	protected String witnessAhlwardtNo;
 
-	private boolean advancedSearch = false;
-	private String resultMode = MODE_NONE;
-	private String resultSummaryMsg;
+	protected boolean advancedSearch = false;
+	protected String resultMode = MODE_NONE;
+	protected String resultSummaryMsg;
 	
-	private String subjectType;
-	private List<SelectItem> suggestedSubjectTypes = new ArrayList<SelectItem>();
+	protected String subjectType;
+	protected List<SelectItem> suggestedSubjectTypes = new ArrayList<SelectItem>();
 	
-	private String referenceBibIdNo;
+	protected String referenceBibIdNo;
 
-	private String page;
-	private String pageMsg;
+	protected String page;
+	protected String pageMsg;
 	
 	public static String main_subject = "main_subject";
 	public static String sub_subject = "sub_subject";
@@ -87,7 +88,7 @@
     /**
      * Put the current subset of this.entites in this.currentEntities.
      */
-    private void updateAdvancedEntities() {
+    protected void updateAdvancedEntities() {
         if (StringUtils.isNotEmpty(getObjectClass())) {
             this.advancedPaginator.initCount();
             int startRecord = this.advancedPaginator.getCurrentPage() * this.advancedPaginator.getItemsPerPage();
@@ -113,37 +114,37 @@
 	public String advancedFirst() {
 		this.advancedPaginator.first();
 		this.updateAdvancedEntities();
-		return GOTO_ENTITY_REPOSITORY;
+		return null; //GOTO_ENTITY_REPOSITORY;
 	}
 
 	public String advancedLast() {
 		this.advancedPaginator.last();
 		this.updateAdvancedEntities();
-		return GOTO_ENTITY_REPOSITORY;
+		return null; //GOTO_ENTITY_REPOSITORY;
 	}
 
 	public String advancedFastForward() {
 		this.advancedPaginator.fastForward();
 		this.updateAdvancedEntities();
-		return GOTO_ENTITY_REPOSITORY;
+		return null; //GOTO_ENTITY_REPOSITORY;
 	}
 
 	public String advancedFastRewind() {
 		this.advancedPaginator.fastRewind();
 		this.updateAdvancedEntities();
-		return GOTO_ENTITY_REPOSITORY;
+		return null; //GOTO_ENTITY_REPOSITORY;
 	}
 
 	public String advancedPrevious() {
 		this.advancedPaginator.previous();
 		this.updateAdvancedEntities();
-		return GOTO_ENTITY_REPOSITORY;
+		return null; //GOTO_ENTITY_REPOSITORY;
 	}
 
 	public String advancedNext() {
 		this.advancedPaginator.next();
 		this.updateAdvancedEntities();
-		return GOTO_ENTITY_REPOSITORY;
+		return null; //GOTO_ENTITY_REPOSITORY;
 	}
 	
 	public void reset(){
@@ -289,6 +290,9 @@
             if (StringUtils.isNotEmpty(this.personNameTranslit)) {
                 filterList.add(new AttributeFilter("name_translit", this.personNameTranslit, PERSON));
             }
+            if (StringUtils.isNotEmpty(this.personMamsNr)) {
+                filterList.add(new AttributeFilter("mams_number", this.personMamsNr, PERSON));
+            }
         }
         
         /*
@@ -431,7 +435,21 @@
 		this.personNameTranslit = personNameTranslit;
 	}
 
-	public String getObjectClass() {
+	/**
+     * @return the personMamsNr
+     */
+    public String getPersonMamsNr() {
+        return personMamsNr;
+    }
+
+    /**
+     * @param personMamsNr the personMamsNr to set
+     */
+    public void setPersonMamsNr(String personMamsNr) {
+        this.personMamsNr = personMamsNr;
+    }
+
+    public String getObjectClass() {
 		return objectClass;
 	}
 
--- a/src/main/java/de/mpiwg/itgroup/ismi/browse/EntityRepositoryBean.java	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/java/de/mpiwg/itgroup/ismi/browse/EntityRepositoryBean.java	Wed Jun 06 21:02:30 2018 +0200
@@ -23,7 +23,7 @@
     
 	private static final long serialVersionUID = -2380877853539157567L;
 	
-	private transient DataPaginator paginator = new DataPaginator();
+	protected transient DataPaginator paginator = new DataPaginator();
 	
 	public EntityRepositoryBean(){
 		super();
@@ -36,7 +36,7 @@
 	}
 
 
-    private void updateEntities() {
+    protected void updateEntities() {
         if (StringUtils.isNotEmpty(getObjectClass())) {
             this.paginator.initCount();
             int startRecord = this.paginator.getCurrentPage() * this.paginator.getItemsPerPage();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/de/mpiwg/itgroup/ismi/browse/FullEntityRepositoryBean.java	Wed Jun 06 21:02:30 2018 +0200
@@ -0,0 +1,176 @@
+package de.mpiwg.itgroup.ismi.browse;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.mpi.openmind.cache.WrapperService;
+import org.mpi.openmind.repository.bo.Attribute;
+import org.mpi.openmind.repository.bo.Entity;
+
+/**
+ * EntityRepositoryBean for full Entities with Attributes and Relations loaded.
+ * 
+ * @author casties
+ *
+ */
+public class FullEntityRepositoryBean extends EntityRepositoryBean {
+
+    private static final long serialVersionUID = 8022526185079972610L;
+
+    protected String sortAttributeName;
+
+    protected boolean sortAttributeNumerically = false;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.mpiwg.itgroup.ismi.browse.AbstractEntityRepositoryBean#
+     * updateAdvancedEntities()
+     */
+    @Override
+    protected void updateAdvancedEntities() {
+        if (StringUtils.isNotEmpty(getObjectClass())) {
+            this.advancedPaginator.initCount();
+            int startRecord = this.advancedPaginator.getCurrentPage() * this.advancedPaginator.getItemsPerPage();
+            if ((this.advancedPaginator.getCurrentPage() + 1) == this.advancedPaginator.getNumberOfPages()) {
+                int mod = this.entities.size() % advancedPaginator.getItemsPerPage();
+                if (mod == 0) {
+                    this.currentEntities = entities.subList(startRecord,
+                            startRecord + this.advancedPaginator.getItemsPerPage());
+                } else {
+                    this.currentEntities = entities.subList(startRecord, startRecord + mod);
+                }
+
+            } else {
+                this.currentEntities = entities.subList(startRecord,
+                        startRecord + this.advancedPaginator.getItemsPerPage());
+            }
+        } else {
+            // empty object_class
+            this.currentEntities = new ArrayList<Entity>();
+        }
+        // make sure all entities are loaded
+        WrapperService store = getWrapper();
+        for (Entity ent : this.currentEntities) {
+            if (ent.isLightweight()) {
+                store.getEntityContent(ent);
+            }
+        }
+    }
+
+    public String actionSortByAttributes() {
+        try {
+            this.sortByAttributes();
+        } catch (Exception e) {
+            printInternalError(e);
+            logger.error(e.getMessage(), e);
+        }
+        return GOTO_ENTITY_REPOSITORY;
+    }
+
+    public void sortByAttributes() throws Exception {
+        this.resultMode = MODE_ADVANCED;
+        this.setPage("");
+        this.entities = new ArrayList<Entity>();
+        this.currentEntities = new ArrayList<Entity>();
+
+        this.resultSummaryMsg = "";
+
+        /*
+         * run search and sort result (by attribute)
+         */
+        List<Entity> resultList = getWrapper().getEntitiesByDef(this.objectClass);
+        // sort List (by ownvalue)
+        Collections.sort(resultList,
+                getEntityAttributeComparator(this.sortAttributeName, this.sortAttributeNumerically));
+        this.entities = resultList;
+
+        if (resultList.size() > 0) {
+            this.resultSummaryMsg = resultList.size() + " items were found!";
+            this.advancedPaginator.setCurrentPage(0);
+            int entitiesCount = this.entities.size();
+            this.advancedPaginator.resetNumberOfPages(entitiesCount);
+            this.updateAdvancedEntities();
+        } else {
+            this.resultSummaryMsg = "No items were found!";
+        }
+    }
+
+    public Comparator<Entity> getEntityAttributeComparator(final String attName, final boolean numerically) {
+        return new Comparator<Entity>() {
+            @Override
+            public int compare(Entity e1, Entity e2) {
+                if (e1.isLightweight()) {
+                    e1 = getWrapper().getEntityContent(e1);
+                }
+                Attribute att1 = e1.getAttributeByName(attName);
+                if (e2.isLightweight()) {
+                    e2 = getWrapper().getEntityContent(e2);
+                }
+                Attribute att2 = e2.getAttributeByName(attName);
+                if (att1 == null && att2 != null) {
+                    return 1;
+                } else if (att1 != null && att2 == null) {
+                    return -1;
+                } else if (att1 == null && att2 == null) {
+                    return 0;
+                }
+                if (numerically) {
+                    Integer a1 = null;
+                    Integer a2 = null;
+                    try {
+                        a1 = Integer.parseInt(att1.getValue());
+                    } catch (Exception e) {
+                    }
+                    try {
+                        a2 = Integer.parseInt(att2.getValue());
+                    } catch (Exception e) {
+                    }
+                    if (a1 == null && a2 != null) {
+                        return 1;
+                    } else if (a1 != null && a2 == null) {
+                        return -1;
+                    } else if (a1 == null && a2 == null) {
+                        return 0;
+                    }
+                   return Integer.compare(a1, a2);
+                } else {
+                    return att1.getValue().compareTo(att2.getValue());
+                }
+            }
+        };
+    }
+
+    /**
+     * @return the sortAttributeName
+     */
+    public String getSortAttributeName() {
+        return sortAttributeName;
+    }
+
+    /**
+     * @param sortAttributeName
+     *            the sortAttributeName to set
+     */
+    public void setSortAttributeName(String sortAttributeName) {
+        this.sortAttributeName = sortAttributeName;
+    }
+
+    /**
+     * @return the sortAttributeNumerical
+     */
+    public boolean isSortAttributeNumerically() {
+        return sortAttributeNumerically;
+    }
+
+    /**
+     * @param sortAttributeNumerical
+     *            the sortAttributeNumerical to set
+     */
+    public void setSortAttributeNumerically(boolean sortAttributeNumerical) {
+        this.sortAttributeNumerically = sortAttributeNumerical;
+    }
+}
--- a/src/main/java/de/mpiwg/itgroup/ismi/entry/beans/SessionBean.java	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/java/de/mpiwg/itgroup/ismi/entry/beans/SessionBean.java	Wed Jun 06 21:02:30 2018 +0200
@@ -27,6 +27,7 @@
 import de.mpiwg.itgroup.ismi.event.beans.TransferEvent;
 import de.mpiwg.itgroup.ismi.merge.GeneralMerge;
 import de.mpiwg.itgroup.ismi.merge.ImportMerge;
+import de.mpiwg.itgroup.ismi.merge.PublicByAuthorBean;
 import de.mpiwg.itgroup.ismi.merge.ReferenceMerge;
 import de.mpiwg.itgroup.ismi.publicView.DynamicPageEditor;
 import de.mpiwg.itgroup.ismi.publicView.PublicCodexBean;
@@ -47,6 +48,7 @@
 	private CopyEvent copyEventForm = new CopyEvent();
 	private TransferEvent transferEventForm = new TransferEvent();
 	private transient AdvancedSearchBean advancedSearch = new AdvancedSearchBean();
+	private transient PublicByAuthorBean publicByAuthor = new PublicByAuthorBean();
 	
 	private EntityDetailsBean entDetailsForm = new EntityDetailsBean();
 	
@@ -137,6 +139,7 @@
 	private String selectedTab = WITNESS_TAB;
 	private String selectedEventTab = WITNESS_STUDY_EVENT_TAB;
 	private String selectedAdvancedSearchTab = "01";
+	private String selectedPublicByAuthorTab = "01";
 	
 
 	private Long editFormCurrentEntId;
@@ -655,6 +658,11 @@
 		this.redirect(null, url);
 	}
 	
+	public void listenerPublicByAuthorTabChange(ItemChangeEvent event) {
+		String url = "?formIndex=" + this.selectedPublicByAuthorTab;
+		this.redirect(null, url);
+	}
+	
 	protected void redirect(String redirectPath, String parameters){
 		FacesContext fc = FacesContext.getCurrentInstance();
 		ExternalContext ec = fc.getExternalContext();
@@ -1099,6 +1107,34 @@
 	public void setPublicCodexBean(PublicCodexBean publicCodexBean) {
 		this.publicCodexBean = publicCodexBean;
 	}
+
+	/**
+	 * @return the publicByAuthor
+	 */
+	public PublicByAuthorBean getPublicByAuthor() {
+		return publicByAuthor;
+	}
+
+	/**
+	 * @param publicByAuthor the publicByAuthor to set
+	 */
+	public void setPublicByAuthor(PublicByAuthorBean publicByAuthor) {
+		this.publicByAuthor = publicByAuthor;
+	}
+
+	/**
+	 * @return the selectedPublicByAuthorTab
+	 */
+	public String getSelectedPublicByAuthorTab() {
+		return selectedPublicByAuthorTab;
+	}
+
+	/**
+	 * @param selectedPublicByAuthorTab the selectedPublicByAuthorTab to set
+	 */
+	public void setSelectedPublicByAuthorTab(String selectedPublicByAuthorTab) {
+		this.selectedPublicByAuthorTab = selectedPublicByAuthorTab;
+	}
 	
 	
 	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/de/mpiwg/itgroup/ismi/merge/PublicByAuthorBean.java	Wed Jun 06 21:02:30 2018 +0200
@@ -0,0 +1,239 @@
+package de.mpiwg.itgroup.ismi.merge;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.event.ActionEvent;
+
+import org.apache.log4j.Logger;
+import org.mpi.openmind.repository.bo.Entity;
+import org.mpi.openmind.repository.bo.Relation;
+
+import de.mpiwg.itgroup.ismi.browse.EntityRepositoryBean;
+import de.mpiwg.itgroup.ismi.browse.FullEntityRepositoryBean;
+import de.mpiwg.itgroup.ismi.entry.beans.AbstractISMIBean;
+
+public class PublicByAuthorBean extends AbstractISMIBean implements Serializable{
+	
+	private static Logger logger = Logger.getLogger(PublicByAuthorBean.class);
+	
+	private static final long serialVersionUID = 1L;
+	
+	private String findAuthorName = "";
+	protected Long selectedPersonId = 0l;
+	
+	protected Entity selectedPerson;
+	protected List<Entity> selectedPersonTexts;
+	protected List<String> selectedPersonSubjects;
+    protected Map<String,List<Entity>> selectedPersonSubjectMap;
+
+    protected Map<String,List<String>> subjectParents;
+
+	
+	private FullEntityRepositoryBean browseBean;
+	
+	
+	public PublicByAuthorBean(){
+		//logger.info("AdvancedSearchBean");
+		this.reset();
+	}
+	
+	public void reset(){
+		//logger.info("AdvancedSearchBean.reset()");
+	    browseBean = new FullEntityRepositoryBean();
+	    browseBean.setObjectClass(PERSON);
+	    
+	    selectedPersonTexts = new ArrayList<Entity>();
+	    selectedPersonSubjectMap = new HashMap<String,List<Entity>>();
+	    makeSubjectTree();
+	}
+	
+	protected void makeSubjectTree() {
+	    subjectParents = new HashMap<String,List<String>>();
+	    List<Entity> subjects = getWrapper().getEntitiesByDef(SUBJECT);
+	    for (Entity subject : subjects) {
+	        if (subject.isLightweight()) {
+	            subject = getWrapper().getEntityContent(subject);
+	        }
+	        ArrayList<String> parents = new ArrayList<String>();
+	        Entity parent = subject;
+	        int cnt = 0; 
+	        do {
+	            if (parent.isLightweight()) {
+	                parent = getWrapper().getEntityContent(parent);
+	            }
+	            List<Relation> parRels = parent.getSourceRelations(is_part_of, SUBJECT);
+	            if (!parRels.isEmpty()) {
+	                Long parentId = parRels.get(0).getTargetId();
+	                parent = getWrapper().getEntityById(parentId);
+	                parents.add(parent.getOwnValue());
+	            } else {
+	                break;
+	            }
+	        } while (++cnt < 5);
+	        subjectParents.put(subject.getOwnValue(), parents);
+	    }
+	}
+	
+	
+	/**
+     * @return the subjectParents
+     */
+    public Map<String, List<String>> getSubjectParents() {
+        return subjectParents;
+    }
+
+    public void listenerAuthorIdSearch(ActionEvent event) {
+        setSelectedPersonById();
+	}
+
+    protected void setSelectedPersonById() {
+        Entity ent = getWrapper().getEntityById(selectedPersonId);
+        if (ent != null) {
+            ent = getWrapper().getEntityContent(ent);
+            selectedPerson = ent;
+            updateSelectedPerson();
+        }
+    }
+	
+    
+
+	public void updateSelectedPerson() {
+	    // load all texts by this author
+	    selectedPersonTexts = new ArrayList<Entity>();
+	    selectedPersonSubjectMap = new HashMap<String,List<Entity>>();
+	    List<Relation> textRels = selectedPerson.getTargetRelations("was_created_by", "TEXT");
+	    for (Relation rel : textRels) {
+	        Long textID = rel.getSourceId();
+	        // get text
+	        Entity text = getWrapper().getEntityByIdWithContent(textID);
+	        selectedPersonTexts.add(text);
+	        // get subject
+	        List<Relation> subjectRels = text.getSourceRelations("has_subject", "SUBJECT");
+            if (subjectRels.isEmpty()) {
+                String subject = "NO SUBJECT";
+                List<Entity> texts = selectedPersonSubjectMap.get(subject);
+                if (texts == null) {
+                    texts = new ArrayList<Entity>();
+                }
+                // add text to list
+                texts.add(text);
+                // add list to subject map
+                selectedPersonSubjectMap.put(subject, texts);
+
+            } else {
+                for (Relation subjectRel : subjectRels) {
+                    Long subjectId = subjectRel.getTargetId();
+                    Entity subject = getWrapper().getEntityByIdWithContent(subjectId);
+                    List<Entity> texts = selectedPersonSubjectMap.get(subject.getOwnValue());
+                    if (texts == null) {
+                        texts = new ArrayList<Entity>();
+                    }
+                    // add text to list
+                    texts.add(text);
+                    // add list to subject map
+                    selectedPersonSubjectMap.put(subject.getOwnValue(), texts);
+                }
+            }
+	    }
+        // update list of subjects
+	    selectedPersonSubjects = new ArrayList<String>();
+	    for (String sub : selectedPersonSubjectMap.keySet()) {
+	        selectedPersonSubjects.add(sub);
+	    }
+	}
+	
+
+	public String actionSelectPerson() {
+       Entity entity = (Entity) getRequestBean("entity");
+       selectedPersonId = entity.getId();
+       setSelectedPersonById();
+       // switch tab
+       getSessionBean().setSelectedPublicByAuthorTab("sub");
+       return null;
+	}
+	
+	public void actionAllAuthors() {
+	    browseBean.setObjectClass(PERSON);
+	    browseBean.setSortAttributeName("mams_number");
+	    browseBean.setSortAttributeNumerically(true);
+	    try {
+            browseBean.sortByAttributes();
+        } catch (Exception e) {
+            logger.error(e);
+        }
+	}
+	
+	/**
+	 * @return the findAuthorName
+	 */
+	public String getFindAuthorName() {
+		return findAuthorName;
+	}
+
+	/**
+	 * @param findAuthorName the findAuthorName to set
+	 */
+	public void setFindAuthorName(String findAuthorName) {
+		this.findAuthorName = findAuthorName;
+	}
+
+    /**
+     * @return the browseBean
+     */
+    public EntityRepositoryBean getBrowseBean() {
+        return browseBean;
+    }
+
+    /**
+     * @return the selectedPersonId
+     */
+    public long getSelectedPersonId() {
+        return selectedPersonId;
+    }
+
+    /**
+     * @param selectedPersonId the selectedPersonId to set
+     */
+    public void setSelectedPersonId(long selectedPersonId) {
+        this.selectedPersonId = selectedPersonId;
+    }
+    /**
+     * @return the selectedPerson
+     */
+    public Entity getSelectedPerson() {
+        return selectedPerson;
+    }
+
+    /**
+     * @return the selectedPersonTexts
+     */
+    public List<Entity> getSelectedPersonTexts() {
+        return selectedPersonTexts;
+    }
+
+    /**
+     * @return the selectedPersonSubjects
+     */
+    public Map<String, List<Entity>> getSelectedPersonSubjectMap() {
+        return selectedPersonSubjectMap;
+    }
+
+    /**
+     * @param selectedPersonId the selectedPersonId to set
+     */
+    public void setSelectedPersonId(Long selectedPersonId) {
+        this.selectedPersonId = selectedPersonId;
+    }
+
+    /**
+     * @return the selectedPersonSubjects
+     */
+    public List<String> getSelectedPersonSubjects() {
+        return selectedPersonSubjects;
+    }
+
+}
--- a/src/main/java/de/mpiwg/itgroup/ismi/search/beans/AdvancedSearchBean.java	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/java/de/mpiwg/itgroup/ismi/search/beans/AdvancedSearchBean.java	Wed Jun 06 21:02:30 2018 +0200
@@ -3,16 +3,12 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import javax.faces.event.ValueChangeEvent;
 import javax.faces.model.SelectItem;
 
 import org.apache.log4j.Logger;
-import org.mpi.openmind.repository.bo.Attribute;
 import org.mpi.openmind.search.utils.ResultEntry;
-import org.mpi.openmind.search.utils.SAttribute;
 import org.mpi.openmind.search.utils.SAttributeMultipleName;
 import org.mpi.openmind.search.utils.SAttributeMultipleValue;
 import org.mpi.openmind.search.utils.SAttributeUniqueName;
@@ -22,8 +18,6 @@
 import org.mpi.openmind.search.utils.SRelationUniqueName;
 
 import de.mpiwg.itgroup.ismi.entry.beans.AbstractISMIBean;
-import de.mpiwg.itgroup.ismi.entry.beans.SessionBean;
-import de.mpiwg.itgroup.ismi.util.guiComponents.Calendar;
 
 public class AdvancedSearchBean extends AbstractISMIBean implements Serializable{
 	
--- a/src/main/java/de/mpiwg/itgroup/ismi/search/beans/Titles4PersonQuery.java	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/java/de/mpiwg/itgroup/ismi/search/beans/Titles4PersonQuery.java	Wed Jun 06 21:02:30 2018 +0200
@@ -2,16 +2,12 @@
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.faces.model.SelectItem;
 
 import org.apache.commons.lang.StringUtils;
 import org.mpi.openmind.repository.bo.Entity;
-import org.mpi.openmind.repository.bo.Relation;
-import org.mpi.openmind.repository.utils.NormalizerUtils;
 import org.mpi.openmind.repository.utils.OldNormalizerUtils;
 import org.mpi.openmind.search.utils.ResultEntry;
 import org.mpi.openmind.search.utils.SAttributeMultipleName;
--- a/src/main/java/de/mpiwg/itgroup/ismi/util/guiComponents/DataPaginator.java	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/java/de/mpiwg/itgroup/ismi/util/guiComponents/DataPaginator.java	Wed Jun 06 21:02:30 2018 +0200
@@ -4,7 +4,7 @@
 
 public class DataPaginator {
 	/* This should be parameters or properties stored somewhere */
-	private int itemsPerPage = 10;
+	private int itemsPerPage = 20;
 	private int rewindFastForwardBy = 10;
 	
 	private int currentPage;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/webapp/clean/components/publicFindAuthor.xhtml	Wed Jun 06 21:02:30 2018 +0200
@@ -0,0 +1,174 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:a4j="http://richfaces.org/a4j"
+	xmlns:rich="http://richfaces.org/rich">
+
+<body>
+	<ui:composition>
+
+   <!-- <h:outputStylesheet name="/css/ismi-db/repository.css" /> -->
+            
+
+
+		<h:panelGrid columns="3" styleClass="displayPanel"
+			columnClasses="displayPanelColumn01,displayPanelColumn02">
+
+            <a4j:commandButton value="show all authors"
+                actionListener="#{Session.publicByAuthor.actionAllAuthors}"
+                render="selectPersonPanel" />
+            <h:outputText/>
+            <h:outputText/>
+
+			<h:panelGrid columns="1">
+				<h:outputLabel value="Person name" />
+				<h:outputLabel value="(name_translit)" />
+			</h:panelGrid>
+			<h:inputText value="#{Session.publicByAuthor.browseBean.personNameTranslit}" />
+			<a4j:commandButton value="search"
+				actionListener="#{Session.publicByAuthor.browseBean.actionSearchByAttributes}"
+				render="selectPersonPanel" />
+
+
+		</h:panelGrid>
+
+		<h:panelGrid id="selectPersonPanel" columns="1"
+			style="margin-left: auto; margin-right: auto; text-align: center; width: 100%;"
+			>
+
+
+			<h:outputText
+				value="#{Session.publicByAuthor.browseBean.resultSummaryMsg}"
+				rendered="#{!empty Session.publicByAuthor.browseBean.resultSummaryMsg}"
+				styleClass="sumaryMsg" />
+
+			<h:column
+				rendered="#{!empty Session.publicByAuthor.browseBean.entities}">
+				<h:outputText value="go to page" styleClass="sumaryMsg" />
+				<h:inputText value="#{Session.publicByAuthor.browseBean.page}"
+					size="4" />
+				<h:commandButton value="submit"
+					actionListener="#{Session.publicByAuthor.browseBean.actionGoToPageAdvancedResult}" />
+				<h:outputText value=" #{Session.publicByAuthor.browseBean.pageMsg}"
+					rendered="#{!empty Session.publicByAuthor.browseBean.pageMsg}"
+					style="color:red" />
+			</h:column>
+
+
+			<h:column
+				rendered="#{!empty Session.publicByAuthor.browseBean.entities}">
+				<h:panelGroup>
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-first.gif"
+						style="border:none;" title="First Page"
+						action="#{Session.publicByAuthor.browseBean.advancedFirst}" />
+
+					<h:commandButton image="/resources/css/xp/css-images/arrow-fr.gif"
+						style="border:none;" title="Fast Backwards"
+						action="#{Session.publicByAuthor.browseBean.advancedFastRewind}" />
+
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-previous.gif"
+						style="border:none;" title="Previous Page"
+						action="#{Session.publicByAuthor.browseBean.advancedPrevious}" />
+
+					<h:outputText
+						value="#{Session.publicByAuthor.browseBean.advancedPaginator.recordStatus}"
+						styleClass="sumaryMsg" />
+
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-next.gif"
+						style="border:none;" title="Next Page"
+						action="#{Session.publicByAuthor.browseBean.advancedNext}" />
+
+					<h:commandButton image="/resources/css/xp/css-images/arrow-ff.gif"
+						style="border:none;" title="Fast Forward"
+						action="#{Session.publicByAuthor.browseBean.advancedFastForward}" />
+
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-last.gif"
+						style="border:none;" title="Last Page"
+						action="#{Session.publicByAuthor.browseBean.advancedLast}" />
+				</h:panelGroup>
+			</h:column>
+
+			<rich:dataTable id="advancedDataTable" rows="30"
+				value="#{Session.publicByAuthor.browseBean.currentEntities}"
+				rendered="#{!empty Session.publicByAuthor.browseBean.currentEntities}"
+				var="entity" styleClass="rsPanel" columnClasses="rsPanelColumn">
+                <h:column style="text-align:left">
+                    <f:facet name="header">MAMS</f:facet>
+                    <h:outputText value="#{entity.getAttributeByName('mams_number').getValue()}" />
+                </h:column>
+				<h:column style="text-align:left">
+                    <f:facet name="header">Person</f:facet>
+					<h:commandLink
+					    rerender="tabPanel"
+						action="#{Session.publicByAuthor.actionSelectPerson}">
+						<h:outputText
+							value="#{entity.ownValue}" />
+					</h:commandLink>
+                    <h:outputLink
+                        value="#{ApplicationBean1.root}/browse/entityDetails.xhtml?eid=#{entity.id}">
+                        <h:outputText
+                            value=" - [#{entity.id}]" />
+                    </h:outputLink>
+					<h:commandButton
+						action="#{Session.publicByAuthor.browseBean.actionEdit}"
+						rendered="#{Session.canEdit}"
+						image="/resources/css/xp/css-images/edit16.gif"
+						title="Edit this entity" />
+				</h:column>
+                <h:column style="text-align:left">
+                    <f:facet name="header">State</f:facet>
+                    <h:outputText value="#{entity.privacity}" />
+                </h:column>
+			</rich:dataTable>
+
+			<h:column
+				rendered="#{!empty Session.publicByAuthor.browseBean.entities}">
+				<h:panelGroup>
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-first.gif"
+						style="border:none;" title="First Page"
+						action="#{Session.publicByAuthor.browseBean.advancedFirst}" />
+
+					<h:commandButton image="/resources/css/xp/css-images/arrow-fr.gif"
+						style="border:none;" title="Fast Backwards"
+						action="#{Session.publicByAuthor.browseBean.advancedFastRewind}" />
+
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-previous.gif"
+						style="border:none;" title="Previous Page"
+						action="#{Session.publicByAuthor.browseBean.advancedPrevious}" />
+
+					<h:outputText
+						value="#{Session.publicByAuthor.browseBean.advancedPaginator.recordStatus}"
+						styleClass="sumaryMsg" />
+
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-next.gif"
+						style="border:none;" title="Next Page"
+						action="#{Session.publicByAuthor.browseBean.advancedNext}" />
+
+					<h:commandButton image="/resources/css/xp/css-images/arrow-ff.gif"
+						style="border:none;" title="Fast Forward"
+						action="#{Session.publicByAuthor.browseBean.advancedFastForward}" />
+
+					<h:commandButton
+						image="/resources/css/xp/css-images/arrow-last.gif"
+						style="border:none;" title="Last Page"
+						action="#{Session.publicByAuthor.browseBean.advancedLast}" />
+				</h:panelGroup>
+			</h:column>
+
+
+		</h:panelGrid>
+
+
+
+	</ui:composition>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/webapp/clean/components/publicShowSubjects.xhtml	Wed Jun 06 21:02:30 2018 +0200
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:a4j="http://richfaces.org/a4j"
+	xmlns:rich="http://richfaces.org/rich">
+
+<body>
+	<ui:composition>
+
+		<!-- <h:outputStylesheet name="/css/ismi-db/repository.css" /> -->
+
+        <h2 style="color:black; text-align:left">Author: #{Session.publicByAuthor.selectedPerson.ownValue}"</h2>
+
+		<h:panelGrid columns="3" styleClass="displayPanel"
+			columnClasses="displayPanelColumn01,displayPanelColumn02">
+
+			<h:outputLabel value="Person ID" />
+			<h:inputText value="#{Session.publicByAuthor.selectedPersonId}" />
+
+			<a4j:commandButton value="search"
+				actionListener="#{Session.publicByAuthor.listenerAuthorIdSearch}"
+				render="selectSubjectPanel" />
+
+		</h:panelGrid>
+
+		<h:panelGrid id="selectSubjectPanel" columns="1"
+			style="margin-left:auto; margin-right:auto; text-align:left; width:100%;">
+			<rich:dataTable
+				value="#{Session.publicByAuthor.selectedPersonSubjects}"
+				var="subject" styleClass="select">
+				<rich:column>
+					<h2 style="margin-top: 1em">
+						#{subject}
+						<ui:repeat
+							value="#{Session.publicByAuthor.subjectParents.get(subject)}"
+							var="parent"> &lt; #{parent}</ui:repeat>
+					</h2>
+
+					<a4j:commandButton value="make these texts and their witnesses public"
+						/>
+
+					<rich:dataTable
+						value="#{Session.publicByAuthor.selectedPersonSubjectMap.get(subject)}"
+						var="text" styleClass="select">
+						<rich:column>
+							    #{text.ownValue}
+					    </rich:column>
+						<rich:column>
+							<h:outputLink
+								value="#{ApplicationBean1.root}/browse/entityDetails.xhtml?eid=#{text.id}"
+								target="_blank">[#{text.id}]</h:outputLink>
+						</rich:column>
+						<rich:column>
+							    #{text.privacity}
+						</rich:column>
+					</rich:dataTable>
+
+				</rich:column>
+			</rich:dataTable>
+
+
+		</h:panelGrid>
+
+
+
+	</ui:composition>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/webapp/clean/publicByAuthor.xhtml	Wed Jun 06 21:02:30 2018 +0200
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:ui="http://java.sun.com/jsf/facelets"
+	xmlns:a4j="http://richfaces.org/a4j"
+	xmlns:rich="http://richfaces.org/rich">
+
+<body>
+	<ui:composition template="/templates/privateTemplate.xhtml">
+
+        <h:outputStylesheet name="/css/ismi-db/repository.css" />
+
+		<ui:define name="privateContent">
+			
+			<div id="pageTitle">
+				<h:outputText value="Public by Author Form" />
+			</div>
+
+			<h:panelGrid columns="1"
+				styleClass="mainPanel">
+
+				<rich:tabPanel id="tabPanel"
+					activeItem="#{Session.selectedPublicByAuthorTab}">
+				
+                    <rich:tab header="Find Author" name="src">
+                        <ui:include src="components/publicFindAuthor.xhtml" />
+                    </rich:tab>
+                    
+                    <rich:tab header="Select by Subject" name="sub">
+                        <ui:include src="components/publicShowSubjects.xhtml" />
+                    </rich:tab>
+				</rich:tabPanel>
+
+			</h:panelGrid>
+
+
+		</ui:define>
+	</ui:composition>
+
+</body>
+</html>
\ No newline at end of file
--- a/src/main/webapp/search/components/titles4Person.xhtml	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/webapp/search/components/titles4Person.xhtml	Wed Jun 06 21:02:30 2018 +0200
@@ -66,25 +66,6 @@
 			<h:panelGrid columns="1"
 				rendered="#{!empty Session.advancedSearch.titles4PersonQuery.rs}">
 
-				<h:panelGrid columns="2">
-					<h:outputLabel value="Export mode (Dirk system)" />
-					<h:selectOneRadio
-						value="#{Session.advancedSearch.titles4PersonQuery.modeExportDirk}"
-						valueChangeListener="#{Session.advancedSearch.titles4PersonQuery.listenerChangeModeExportDirk}"
-						partialSubmit="true">
-						<f:selectItems
-							value="#{Session.advancedSearch.titles4PersonQuery.modeExportDirkList}" />
-					</h:selectOneRadio>
-				</h:panelGrid>
-
-				<h:outputLink
-					value="#{Session.advancedSearch.titles4PersonQuery.exportDirkUrl}"
-                    target="_blank">
-					<h:outputText
-						value="https://ismi-dev.mpiwg-berlin.mpg.de/zope-ismi/database/export..."
-						style="color:#2200C1;font-size:small;cursor:pointer;text-decoration:underline" />
-				</h:outputLink>
-
 				<rich:dataTable var="entry"
 					value="#{Session.advancedSearch.titles4PersonQuery.rs}"
 					paginator="true" rows="20">
@@ -139,7 +120,7 @@
 
 					<h:column>
 						<f:facet name="header">
-							<h:outputText value="Tilte ID" />
+							<h:outputText value="Title ID" />
 						</f:facet>
 						<h:outputText value="#{entry.titleId}" />
 					</h:column>
--- a/src/main/webapp/templates/main_template.xhtml	Tue May 29 21:16:46 2018 +0200
+++ b/src/main/webapp/templates/main_template.xhtml	Wed Jun 06 21:02:30 2018 +0200
@@ -167,6 +167,18 @@
                 </rich:menuItem>
             </rich:dropDownMenu>
 
+            <rich:dropDownMenu mode="ajax" rendered="#{Session.canMerge}">
+                <f:facet name="label">
+                    <h:panelGroup>
+                        <h:outputText value="Clean" />
+                    </h:panelGroup>
+                </f:facet>
+
+                <rich:menuItem label="Public by author"
+                    onclick="document.location.href='#{ApplicationBean1.root}/clean/publicByAuthor.xhtml'">
+                </rich:menuItem>
+			</rich:dropDownMenu>
+
 			<h:outputLink  rendered="#{Session.canCreate}"
 				value="#{ApplicationBean1.root}/browse/entityRepository.xhtml">Browse Repository</h:outputLink>
 
@@ -188,7 +200,7 @@
 			</rich:dropDownMenu>
 			
 			<h:outputLink rendered="#{Session.canCreate}"
-				value="#{ApplicationBean1.root}/public/publicCodices.xhtml">Codices marked as public</h:outputLink>
+				value="#{ApplicationBean1.root}/public/publicCodices.xhtml">Public Codices</h:outputLink>
 			
 			<h:outputLink  rendered="#{Session.admin}"
 				value="#{ApplicationBean1.root}/search/biographies.xhtml">Biographies</h:outputLink>