/* * Copyright 2011 Uwe Krueger. * * 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 com.mandelsoft.mand.tools; import com.mandelsoft.mand.IllegalConfigurationException; import java.io.File; import java.io.IOException; import com.mandelsoft.mand.Environment; import com.mandelsoft.mand.MandelConstants; import com.mandelsoft.io.AbstractFile; import com.mandelsoft.mand.ColormapName; import com.mandelsoft.mand.QualifiedMandelName; import com.mandelsoft.mand.Settings; import com.mandelsoft.mand.scan.ElementHandle; import com.mandelsoft.mand.scan.MandelHandle; import com.mandelsoft.mand.scan.MandelScanner; import com.mandelsoft.mand.util.MandelList; import com.mandelsoft.mand.util.MandelListFolder; import com.mandelsoft.mand.util.MandelListFolderTree; import com.mandelsoft.mand.tools.Sync.SyncHandler; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * * @author Uwe Krüger */ public class Sync extends Copy<SyncHandler> { static public final int IMAGES = 1; static public final int REQUESTS = 2; static public final int VARIANTS = 4; static public final int AREACOLMAPS = 8; static public final int COLORMAPS = 16; static public final int MANDEL = IMAGES|REQUESTS|VARIANTS|AREACOLMAPS; static public final int ALL = MANDEL|COLORMAPS; ////////////////////////////////////////////////////////////////////// public interface SyncHandler extends ExecutionHandler { void syncList(MandelList ml, MandelList dl, String name); Set<QualifiedMandelName> syncTree(MandelListFolderTree ml, MandelListFolderTree dl, String name); } public class DefaultSyncHandler extends DefaultHandler implements SyncHandler { public void syncList(MandelList ml, MandelList dl, String msg) { System.out.println("syncing list "+msg+"..."); if (dl!=null&&ml!=null) { if (listCopyMode) dl.clear(); dl.addAll(ml); try { dl.save(); } catch (IOException ex) { Warning("cannot write "+msg+": "+ex); } } } public Set<QualifiedMandelName> syncTree(MandelListFolderTree ml, MandelListFolderTree dl, String msg) { Set<QualifiedMandelName> set=new HashSet<QualifiedMandelName>(); Set<QualifiedMandelName> old=new HashSet<QualifiedMandelName>(); System.out.println("syncing tree "+msg+"..."); for (QualifiedMandelName q:dl.getRoot().allentries()) { old.add(q); } if (dl!=null&&ml!=null) { sync(" ", ml.getRoot(), dl.getRoot(), set, old); try { dl.save(); } catch (IOException ex) { Warning("cannot write "+msg+": "+ex); } } return set; } private void sync(String gap, MandelListFolder s, MandelListFolder d, Set<QualifiedMandelName> set, Set<QualifiedMandelName> old) { String ngap=gap+" "; System.out.println(gap+"syncing folder "+s.getPath()); List<QualifiedMandelName> list=new ArrayList<QualifiedMandelName>(); MandelList l=s.getMandelList(); if (!listCopyMode && l!=null) for (QualifiedMandelName n:l) { list.add(n); if (!old.contains(n)) { set.add(n); System.out.println(ngap+"adding "+n); } else { //System.out.println(ngap+"keeping "+n); } } l=d.getMandelList(); if (l!=null) { for (QualifiedMandelName n:d.getMandelList()) { if (!list.contains(n)) { list.add(n); } } l.clear(); l.addAll(list); } // sync sub folders for (MandelListFolder f :s) { MandelListFolder n=d.getSubFolder(f.getName()); if (n==null) n=d.createSubFolder(f.getName()); sync(ngap,f, n, set, old); } if (listCopyMode) { for (MandelListFolder f: d) { MandelListFolder n=s.getSubFolder(f.getName()); if (n==null) d.remove(f); } } } } public class VerboseSyncHandler extends VerboseHandler implements SyncHandler { public void syncList(MandelList ml, MandelList dl, String name) { System.out.println("syncing list "+name); } public Set<QualifiedMandelName> syncTree(MandelListFolderTree ml, MandelListFolderTree dl, String name) { System.out.println("syncing tree "+name); return new HashSet<QualifiedMandelName>(); } } ////////////////////////////////////////////////////////////////////// // additional file types private class ColormapType extends FileType { ColormapType() { super("colormaps", MandelScanner.COLORMAP, src==null?null:src.getColormapScanner(), dst.getColormapScanner()); handlePath(Settings.COLORMAP_SAVE_PATH); } @Override protected boolean has(ElementHandle h) { String n=h.getFile().getName(); if (n.endsWith(MandelConstants.COLORMAP_SUFFIX)) n=n.substring(0,n.length()-3); return !dstscan.getColormapHandles(new ColormapName(n)).isEmpty(); } @Override protected boolean use(ElementHandle h) { return true; } } /////////////////////////////////////////////////////////////////////////// // Sync class protected int typecodes; protected boolean listCopyMode=false; public Sync(Environment src, Environment dst) { this(src,dst,ALL); } public Sync(Environment src, Environment dst, int types) { super(src,dst); this.typecodes=types; this.types.clear(); if ((types&REQUESTS)!=0) { this.types.add(new InfoType()); } if ((types&IMAGES)!=0) { this.types.add(new AreaColmapType()); this.types.add(new RasterType()); this.types.add(new RasterImageType()); } if ((types&COLORMAPS)!=0) { this.types.add(new ColormapType()); } } public void setListCopyMode(boolean listCopyMode) { this.listCopyMode=listCopyMode; } ////////////////////////////////////////////////////////////////////// @Override protected String map(AbstractFile s) { return s.getName(); } @Override protected boolean handleFile(FileType ft, ElementHandle h) { boolean v; AbstractFile mf=h.getFile(); if (mf.getName().startsWith("x")) { System.out.println(" "+mf); v=true; } else v=false; //v=true; //System.out.println("checking "+mf); if ((typecodes&VARIANTS)==0 && h.getHeader().hasInfo()) { if (((MandelHandle)h).getQualifier()!=null) return false; } if (!ft.has(h)) { if (ft.use(h)) { return ft.handle(h); } else { if (v) System.out.println(" skipped"); } } else { if (v) { System.out.println(" already exists "+mf); } } return false; } /////////////////////////////////////////////////////////////////////////// @Override protected void additionalSteps() { if (exec.getClass()!=VerboseSyncHandler.class) { exec.syncTree(src.getFavorites(),dst.getFavorites(),"favorites"); exec.syncTree(src.getTodos(),dst.getTodos(),"todos"); exec.syncTree(src.getLinks(),dst.getLinks(),"links"); exec.syncList(src.getSeenRasters(),dst.getSeenRasters(),"seen"); exec.syncList(src.getAreas(),dst.getAreas(),"areas"); for (MandelListFolderTree t:src.getUserLists()) { if (t.getRoot().getName().equals("news")) continue; for (MandelListFolderTree d:dst.getUserLists()) { if (t.getRoot().getName().equals(d.getRoot().getName())) { exec.syncTree(t,d,t.getRoot().getName()); } } } } } /////////////////////////////////////////////////////////////////////////// protected static int parseTypes(int c, String[] args) { int types=ALL; if (args.length>c) { if (args[c].startsWith("-")) { types=ALL; } else { types = 0; } while (args.length>c) { String t=args[c++]; boolean sub=false; int type=0; if (t.startsWith("-")) { sub=true; t=t.substring(1); } else { if (t.startsWith("+")) { sub=false; t=t.substring(1); } } if (t.equals("requests")) { type=REQUESTS; } else if(t.equals("images")) { type=IMAGES; } else if (t.equals("mandel")) { type=MANDEL; } else if(t.equals("variants")) { type=VARIANTS; } else if (t.equals("colormaps")) { type=COLORMAPS; } else if (t.equals("all")) { type=ALL; } else if (t.equals("none")) { type=ALL; sub=true; } else { Error("illegal mode '"+t+"'"); } if (sub) types&=~type; else types|=type; } } return types; } public static void main(String[] args) { try { int c=0; boolean vflag=false; boolean cflag=false; File src=new File("F://Mandel2"); File dst=new File("F://Mandel"); int types; while (args.length>c&&args[c].charAt(0)=='-') { for (int i=1; i<args[c].length(); i++) { char opt; switch (opt=args[c].charAt(i)) { case 'v': vflag=true; break; case 'c': cflag=true; break; default: Error("illegal option '"+opt+"'"); } } c++; } if (args.length>c) src=new File(args[c++]); if (args.length>c) dst=new File(args[c++]); types=parseTypes(c, args); System.out.println("syncing from "+src+" to "+dst+" (types="+types+")"); if (!src.isDirectory()) Error(src+" is no directory"); if (!dst.isDirectory()) Error(dst+" is no directory"); Environment env_src=new Environment("mandtool", null, src); Environment env_dst=new Environment("mandtool", null, dst); Sync a=new Sync(env_src, env_dst, types); a.setListCopyMode(cflag); if (vflag) { a.setExecutionHandler(a.new VerboseSyncHandler()); } else { a.setExecutionHandler(a.new DefaultSyncHandler()); } a.execute(); System.out.println(""+a.count+" copied"); } catch (IllegalConfigurationException ex) { Error("illegal config: "+ex); } } }