/* * 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.srv; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Set; import com.mandelsoft.mand.Environment; import com.mandelsoft.io.FolderLock; import com.mandelsoft.mand.MandIter; import com.mandelsoft.mand.MandelData; import com.mandelsoft.io.AbstractFile; import com.mandelsoft.mand.MandelFileName; import com.mandelsoft.mand.MandelInfo; import com.mandelsoft.mand.PixelIterator; import com.mandelsoft.mand.cm.ColormapModel.ResizeMode; import com.mandelsoft.mand.scan.MandelHandle; import com.mandelsoft.mand.scan.MandelScanner; import com.mandelsoft.mand.util.MandUtils; import com.mandelsoft.util.ChangeEvent; import com.mandelsoft.util.ChangeListener; import com.mandelsoft.util.StateChangeSupport; /** * * @author Uwe Krüger */ public class ImageHandler implements Request { private AbstractFile mandelfile; private MandelFileName name; private Environment env; private boolean accepted; public ImageHandler(Environment env, AbstractFile f) { this.mandelfile=f; this.env=env; } public boolean isAccepted() { return accepted; } ////////////////////////////////////////////////////////////////// // handling the request ////////////////////////////////////////////////////////////////// private Exception err; private FolderLock lock; private Server server; private long starttime; public void send(Server server) { MandelScanner imagescan; this.server=server; accepted=false; name=MandelFileName.create(mandelfile); imagescan=env.getImageDataScanner(); if (name==null) return; try { MandelData old=null; lock=new FolderLock(mandelfile.getFile()); if (!lock.lock()) return; try { if (!mandelfile.tryLock()) return; } finally { lock.releaseLock(); } System.out.println("got lock for "+mandelfile); MandelData req; try { req=new MandelData(mandelfile, false); } catch (IOException io) { mandelfile.releaseLock(); if (mandelfile.getFile().length()==0) mandelfile.getFile().delete(); return; } MandelInfo reqd=req.getInfo(); Set<MandelHandle> set=imagescan.getMandelHandles(name.getQualifiedName()); if (!set.isEmpty()) { for (MandelHandle h:set) { if (h.getHeader().hasRaster()) { try { MandelData md=h.getData(); MandelInfo mi=md.getInfo(); System.out.println("requested "+reqd.getLimitIt()+ " found "+h.getFile()+": "+mi.getLimitIt()); if (reqd.getDX().equals(mi.getDX())&& reqd.getDY().equals(mi.getDY())&& reqd.getXM().equals(mi.getXM())&& reqd.getYM().equals(mi.getYM())&& reqd.getRX()==mi.getRX()&& reqd.getRY()==mi.getRY()) { old=md; break; } } catch (IOException io) { } } } if (old==null||old.getInfo().getLimitIt()>=reqd.getLimitIt()) { System.out.println(mandelfile+" skipped"); lock.lock(); try { mandelfile.releaseLock(); cleanupInfo(env, mandelfile); } finally { lock.releaseLock(); } return; } } setup(req,old); start(); } catch (IOException io) { System.err.println("*** "+mandelfile+": "+io); } } private void start() { boolean recalc=md.getRaster()!=null; System.out.println((recalc?"re":"")+ "calculating "+(file==null?"":file)+"..."); if (md.getRaster()!=null&&md.getInfo().getMaxIt()>limit) { System.out.println("nothing to be done"); return; } starttime=System.currentTimeMillis(); ImageData data=new ImageData(name,recalc,pi.getPrecision(), pi.getMagnification(),starttime); server.addImage(data); if (!recalc) mi.setTime(0); raster=md.createRaster().getRaster(); AreaHandler area=new AreaHandler(server, recalc, true, md, 0, 0, mi.getRX(), mi.getRY()); area.setPixelIterator(pi); area.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { AreaHandler area=(AreaHandler)e.getSource(); mi.setTime(mi.getTime()+(int)(area.getMTime()/1000)); done(); } }); accepted=true; area.send(server); // mi.setTime(mi.getTime()+(int)((end-start)/1000));; } private void done() { long end=System.currentTimeMillis(); int efftime=(int)((end-starttime)/1000); mi.setEffectiveTime(efftime); mi.setRasterCreationTime(end); server.removeImage(name); try { write(false); lock.lock(); try { mandelfile.releaseLock(); System.out.println("release lock for "+mandelfile); if (!mandelfile.getName().equals(getFile().getName())) { cleanupInfo(env, mandelfile); } } finally { lock.releaseLock(); } } catch (IOException io) { err=io; System.err.println("*** "+mandelfile+": "+io); } listeners.fireChangeEvent(this); } public AbstractFile getMandelFile() { return mandelfile; } public Exception getError() { return err; } /////////////////////////////////////////////////////////////////// // calculation /////////////////////////////////////////////////////////////////// private File file; private MandelData md; private MandelInfo mi; private PixelIterator pi; private int limit; private int[][] raster; public void setPixelIterator(PixelIterator pi) { this.pi=pi; } private void setup(MandelData md) { this.md=md; this.mi=md.getInfo(); this.limit=mi.getLimitIt(); this.file=env.mapToRasterFile(md.getFile()); } private void setup(MandelData md, MandelData old) throws IOException { setup(md); if (old!=null && old.getFile().isFile()) { md.setRaster(old.getRaster()); md.setMapper(ResizeMode.RESIZE_LOCK_COLORS, old.getMapper()); mi.setSite(old.getInfo().getSite()); mi.setCreator(old.getInfo().getCreator()); mi.setLocation(old.getInfo().getLocation()); mi.setName(old.getInfo().getName()); this.file=old.getFile().getFile(); } else { this.file=env.mapToRasterFile(md.getFile()); } pi=MandIter.createPixelIterator(mi); System.out.println("precision set to "+pi.getPrecision()+ "("+pi.getMagnification()+")"); mi.setMinIt(limit); } public File getFile() { return file; } private void write(boolean verbose) throws IOException { if (file==null) throw new IOException("no file specified"); md.write(file,verbose); System.out.println(new Date()+": "+file+" done: "+MandUtils.time(md.getInfo().getTime())); } //////////////////////////////////////////////////////////////////////// // events //////////////////////////////////////////////////////////////////////// private StateChangeSupport listeners=new StateChangeSupport(); public void addChangeListener(ChangeListener l) { listeners.addChangeListener(l); } public void removeChangeListener(ChangeListener l) { listeners.removeChangeListener(l); } static private void cleanupInfo(Environment env, AbstractFile f) { if (!env.backupInfoFile(f)) { if (env.isCleanupInfo() && f.isFile()) { System.out.println("deleting "+f); f.getFile().delete(); } } } }