package org.korsakow.domain.command; import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.Set; import javax.xml.xpath.XPathExpressionException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dsrg.soenea.domain.MapperException; import org.dsrg.soenea.domain.command.CommandException; import org.dsrg.soenea.environment.CreationException; import org.dsrg.soenea.environment.KeyNotFoundException; import org.dsrg.soenea.uow.UoW; import org.korsakow.domain.Snu; import org.korsakow.domain.interf.IDynamicProperties; import org.korsakow.domain.interf.IInterface; import org.korsakow.domain.interf.IProject; import org.korsakow.domain.interf.IResource; import org.korsakow.domain.interf.IRule; import org.korsakow.domain.interf.ISnu; import org.korsakow.domain.interf.IWidget; import org.korsakow.domain.mapper.input.MapperHelper; import org.korsakow.domain.mapper.input.ProjectInputMapper; import org.korsakow.domain.mapper.input.ResourceInputMapper; public class RemoveReferencesToResourceCommand extends AbstractCommand{ private final Log log = LogFactory.getLog(getClass()); private IProject project; public RemoveReferencesToResourceCommand(Helper request, Helper response) { super(request, response); } public void execute() throws CommandException { try { project = ProjectInputMapper.find(); IResource referent = ResourceInputMapper.map(request.getLong("id")); Set<IResource> dirty = new HashSet<IResource>(); Set<IResource> locked = new HashSet<IResource>(); if (referent instanceof ISnu) { ISnu snu = (ISnu) referent; if (snu.getMainMedia() != null) { IResource mainMedia = snu.getMainMedia(); Collection<IResource> references = MapperHelper.findResourcesReferencing(mainMedia.getId()); for (IResource referrer : references) { if (removeReferences(referrer, mainMedia)) { UoW.getCurrent().registerDirty(referrer); dirty.add(referrer); } else { locked.add(referrer); log.warn(String.format("unexpected: referrer(%s)'s reference(%s) not removed", referrer.getName(), mainMedia.getName())); } } } } Collection<IResource> references = MapperHelper.findResourcesReferencing(referent.getId()); for (IResource referrer : references) { if (removeReferences(referrer, referent)) { UoW.getCurrent().registerDirty(referrer); dirty.add(referrer); } else { locked.add(referrer); log.warn(String.format("unexpected: referrer(%s)'s reference(%s) not removed", referrer.getName(), referent.getName())); } } response.set("resourceInUse", true); response.set("references", dirty); response.set("lockedBy", locked); UoW.getCurrent().commit(); UoW.newCurrent(); } catch (MapperException e) { throw new CommandException(e); } catch (SQLException e) { throw new CommandException(e); } catch (KeyNotFoundException e) { throw new CommandException(e); } catch (CreationException e) { throw new CommandException(e); } catch (XPathExpressionException e) { throw new CommandException(e); } } private boolean removeReferences(IResource from, IResource to) { if (from == null || to == null) throw new NullPointerException(); boolean dirty = false; if (from instanceof ISnu && removeReferences((ISnu)from, to)) dirty = true; if (from instanceof IInterface && removeReferences((IInterface)from, to)) dirty = true; if (from instanceof IWidget && removeReferences((IWidget)from, to)) dirty = true; if (from instanceof IRule && removeReferences((IRule)from, to)) dirty = true; if (from instanceof IProject && removeReferences((IProject)from, to)) dirty = true; if (from instanceof IDynamicProperties && removeReferences((IDynamicProperties)from, to)) dirty = true; return dirty; } private boolean removeReferences(IRule from, IResource to) { return false; } private boolean removeReferences(ISnu from, IResource to) { if (from == null || to == null) throw new NullPointerException(); boolean dirty = false; if (to.equals(from.getBackgroundSound())) { from.setBackgroundSound(null); from.setBackgroundSoundMode(Snu.DEFAULT_BACKGROUNDSOUNDMODE); dirty = true; } if (to.equals(from.getMainMedia())) { // TODO: it would be nice to be ale to add messages here indicating why this case is invalid } if (to.equals(from.getPreviewMedia())) { from.setPreviewMedia(null); dirty = true; } if (to.equals(from.getInterface())) { if ( !to.equals( project.getDefaultInterface() ) ) { from.setInterface( project.getDefaultInterface() ); dirty = true; } } return dirty; } private boolean removeReferences(IInterface from, IResource to) { boolean dirty = false; if (to.equals(from.getClickSound())) { from.setClickSound(null); dirty = true; } return dirty; } private boolean removeReferences(IWidget from, IResource to) { return false; } private boolean removeReferences(IProject from, IResource to) { boolean dirty = false; if (to.equals(from.getBackgroundImage())) { from.setBackgroundImage(null); dirty = true; } if (to.equals(from.getBackgroundSound())) { from.setBackgroundSound(null); dirty = true; } if (to.equals(from.getClickSound())) { from.setClickSound(null); dirty = true; } if (to.equals(from.getSplashScreenMedia())) { from.setSplashScreenMedia(null); dirty = true; } return dirty; } private boolean removeReferences(IDynamicProperties from, IResource to) { boolean dirty = false; Collection<String> ids = new HashSet<String>(from.getDynamicPropertyIds()); // concurrent modification for (String id : ids) { // TODO: this is a terrible way of checking but at the moment its the best we can do. if (!id.endsWith("Id")) continue; if (from.getDynamicProperty(id) != null && (from.getDynamicProperty(id).equals(to.getId()) || from.getDynamicProperty(id).equals(""+to.getId())) // this really sucks, I hope to fix the DynamicProperties soon. ) { from.setDynamicProperty(id, null); dirty = true; } } return dirty; } }