package org.openedit.entermedia.cluster;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
import org.apache.lucene.index.IndexWriter;
import org.openedit.Data;
import org.openedit.data.BaseData;
import org.openedit.data.lucene.BaseLuceneSearcher;
import org.openedit.repository.ContentItem;
import org.openedit.util.DateStorageUtil;
import com.openedit.hittracker.HitTracker;
import com.openedit.hittracker.SearchQuery;
import com.openedit.page.manage.PageManager;
import com.openedit.util.PathUtilities;
public class DataFileSearcher extends BaseLuceneSearcher
{
protected PageManager fieldPageManager;
public PageManager getPageManager()
{
return fieldPageManager;
}
public void setPageManager(PageManager inPageManager)
{
fieldPageManager = inPageManager;
}
public Data createNewData()
{
return new BaseData();
}
public void reIndexAll(IndexWriter inWriter, TaxonomyWriter inTaxonomyWriter)
{
//loop over all the files
//super.reIndexAll();
ContentItem root = getPageManager().getRepository().getStub("/WEB-INF/data/" + getCatalogId());
addFolderToIndex(root,inWriter, inTaxonomyWriter);
}
protected void addFolderToIndex(ContentItem inRoot, IndexWriter inWriter ,TaxonomyWriter inTaxonomyWriter)
{
List childrenItems = listChildren(inRoot.getPath());
List tosavelist = new ArrayList();
for (Iterator iterator = childrenItems.iterator(); iterator.hasNext();)
{
String path = (String) iterator.next();
ContentItem item = getPageManager().getRepository().getStub(path);
Data tosave = createNewData(item);
tosavelist.add(tosave);
if( item.isFolder())
{
addFolderToIndex(item, inWriter, inTaxonomyWriter);
}
}
updateIndex(inWriter, inTaxonomyWriter, tosavelist);
}
protected List listChildren(String inPath)
{
List children = getPageManager().getChildrenPaths(inPath);
List copy = new ArrayList(children);
for (Iterator iterator = children.iterator(); iterator.hasNext();)
{
String path = (String) iterator.next();
if( path.endsWith("/CVS") || path.endsWith("/index") || path.endsWith("/.versions"))
{
copy.remove(path);
}
}
return copy;
}
public void updateFileList()
{
//loop over all the files in the datadirectory
//do one folder at a time
ContentItem root = getPageManager().getRepository().getStub("/WEB-INF/data/" + getCatalogId());
List todelete = new ArrayList();
List toadd = new ArrayList();
List tosave = new ArrayList();
processFileList(root, todelete, toadd, tosave);
saveChanges(todelete,toadd, tosave);
}
protected void processFileList(ContentItem inRoot, List inToDelete, List inToAdd, List inToSave)
{
List childrenItems = listChildren(inRoot.getPath());
Map lookup = new HashMap(childrenItems.size());
for (Iterator iterator = childrenItems.iterator(); iterator.hasNext();)
{
String path = (String)iterator.next();
ContentItem item = getPageManager().getRepository().getStub(path);
lookup.put(item.getPath(), item);
}
processFileList(inRoot,lookup, inToDelete, inToAdd, inToSave);
}
protected void processFileList(ContentItem inRoot,Map inChildrenItems, List inToDelete, List inToAdd, List inToSave)
{
SearchQuery query = createSearchQuery();
query.addExact("folder",inRoot.getId());
//query.addSortBy("folderDown");
HitTracker tracker = search(query);
// Collection allfiles = new ArrayList(inChildrenItems.values());
mergeChanges(tracker, inRoot, inChildrenItems, inToDelete, inToAdd, inToSave);
if( inToDelete.size() > 1000 || inToAdd.size() > 1000 || inToSave.size() > 1000)
{
saveChanges(inToDelete,inToAdd, inToSave);
}
for (Iterator iterator = inChildrenItems.values().iterator(); iterator.hasNext();)
{
ContentItem child = (ContentItem) iterator.next();
if( child.isFolder())
{
processFileList( child, inToDelete, inToAdd, inToSave);
}
}
}
protected void saveChanges(List inToDelete, List inToAdd, List inToEdit)
{
List tosave = new ArrayList();
tosave.addAll(inToDelete);
tosave.addAll(inToAdd);
tosave.addAll(inToEdit);
clearIndex();
//getLiveSearcher();
updateIndex(tosave);
}
protected void mergeChanges(HitTracker inPreviousHits, ContentItem inRoot, Map inActualItems, List<Data> inToDelete, List<Data> inToAdd, List<Data> inToEdit)
{
List<ContentItem> remaining = new ArrayList<ContentItem>(inActualItems.values());
for (Iterator iterator = inPreviousHits.iterator(); iterator.hasNext();)
{
Data hit = (Data) iterator.next();
String path = hit.get("path");
ContentItem item = (ContentItem)inActualItems.get(path);
if( item == null )
{
Data todelete = createNewData();
String id = PathUtilities.makeId(path);
todelete.setId(id);
todelete.setProperty("path",path);
todelete.setProperty("folder",inRoot.getId());
todelete.setProperty("status", "deleted");
//TODO: Look in .versions for delete record timestamp
todelete.setProperty("lastmodified", DateStorageUtil.getStorageUtil().formatForStorage(new Date()));
inToDelete.add(hit);
}
else
{
//did it change?
if( !item.isFolder())
{
Date lastmod = inPreviousHits.getDateValue(hit, "lastmodified");
String length = hit.get("length");
long flastmod = item.getLastModified();
String flength = String.valueOf( item.getLength() );
if( lastmod.getTime() != flastmod || !length.equals(flength ) )
{
Data modified = createNewData(item);
inToEdit.add(modified);
}
}
remaining.remove(item);
}
}
//anything left in children needs to be added
for (Iterator iterator = remaining.iterator(); iterator.hasNext();)
{
ContentItem item = (ContentItem) iterator.next();
inToAdd.add(createNewData(item));
}
}
protected Data createNewData(ContentItem inItem)
{
Data data = createNewData();
data.setId( inItem.getId());
String folder = inItem.getPath();
folder = PathUtilities.extractDirectoryPath(folder); //go up a level
data.setProperty("folder", PathUtilities.makeId(folder) );
data.setProperty("path", inItem.getPath());
String mod = DateStorageUtil.getStorageUtil().formatForStorage(inItem.lastModified());
data.setProperty("lastmodified", mod);
data.setProperty("length", String.valueOf( inItem.getLength()) );
return data;
}
}