alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.modules.xml.core.sync;

import java.io.*;

import org.openide.loaders.*;
import org.openide.cookies.*;
import org.openide.nodes.*;
import org.openide.filesystems.*;
import org.openide.util.*;
import java.util.Vector;
import java.util.Arrays;

/**
 * A generic support for synchronizing text, tree and file representation
 * of a DataObject. It can be notifified about a change in any of the above
 * representations by:
 * 
  • treeChanged() at TreeEditorSupport *
  • textChanged() at TextEditorSupport *
  • fileChanged() at FileObject * it then propagates change to other representation by calling ...Impl methods * of above (vitrual methods of extending classes). This support should * break possible cycles in ...Impl methods if synchronous implementation is used. * *

    * It is passive object it must be controlled by calling representationChanged() * from e.g. listeners. * * @author Petr Kuzel * @version 1.0 */ public abstract class SyncSupport { private /*final*/ DataObject dobj; /** Just performing synchronization. */ protected static final int JUST_SYNCHRONIZING = 1; /** Conflict alleared, waiting for user selection. */ protected static final int JUST_RESOLVING_CONFLICT = 2; /** Inactive */ protected static final int NOP = 0; private int syncOperation; // current operation // lock that synchronizes access to all above fields private final Object syncOperationLock = new SyncSupportLock(); //~~~~~~~~~~~~~~~~~~ INIT ~~~~~~~~~~~~~~~~~~~~~~~~~ /** Creates new SyncSupport */ public SyncSupport (DataObject dobj) throws IllegalArgumentException { if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("Creating sychronizator " + System.identityHashCode(this) + " for: " + dobj.getPrimaryFile() ); // NOI18N this.dobj = dobj; syncOperation = NOP; } // wait until private void waitFor(int state) throws InterruptedException { while (getSyncOp() != NOP) syncOperationLock.wait(); } // change state private void setSyncOp(int op) { synchronized (syncOperationLock) { if (op == syncOperation) return; if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ( "" + System.identityHashCode(this) + " syncOperation " + syncOperation + " => " + op + " Thread:" + Thread.currentThread().getName()); // NOI18N syncOperation = op; syncOperationLock.notifyAll(); } } private int getSyncOp() { synchronized (syncOperationLock) { if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("" + System.identityHashCode(this) + " syncOperation = " + syncOperation + " Thread:" + Thread.currentThread().getName()); // NOI18N return syncOperation; } } /** * @return true if just synchronizing i.e. no other sync call would succed */ public boolean isInSync() { return getSyncOp() == JUST_SYNCHRONIZING; } /** * It is thread save way how to enter synchronizator. */ public void postRequest(Runnable task) { boolean leave = false; try { synchronized (syncOperationLock) { waitFor(NOP); leave = true; setSyncOp(JUST_SYNCHRONIZING); } task.run(); } catch (InterruptedException ex) { // let finally does it } finally { if (leave) setSyncOp(NOP); } } /** * Retrieve cookie from associated DataObject. */ protected final Node.Cookie getCookie(Class klass) { return getDO().getCookie(klass); } /** * @return DataObject this object is serving for */ protected final DataObject getDO() { return dobj; } // ~~~~~~~~~~~~~~~~~~ Representations management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * A new model appeared. * It may my change result returned by getRepresentations(). */ public abstract void addRepresentation(Representation rep); /** * Some model disppeared. * It may my change result returned by getRepresentations(). */ public abstract void removeRepresentation(Representation rep); /** * Propagate change to other representations. */ protected void representationChanged(Class type) { if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("" + System.identityHashCode(this) + " entering synchronizator: " + type); // NOI18N if (isInSync()) return; //??? prevent double enter if update() fires try { setSyncOp(JUST_SYNCHRONIZING); Representation master = null; Representation all[] = getRepresentations(null); if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("\tReps: " + Arrays.asList(all)); // NOI18N // look for comodifications Vector modified = new Vector(); for (int i=0; i 1) { master = selectMasterRepresentation((Representation[])modified.toArray(new Representation[0])); } if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("\t" + System.identityHashCode(this) + " master: " + master); // NOI18N if (master == null) return; // propagate for (int i=0; i" : " ") + choices[i]); // NOI18N // } return choices[0]; } /** Just for better thread dumps. */ private static class SyncSupportLock { } }

  • ... this post is sponsored by my books ...

    #1 New Release!

    FP Best Seller

     

    new blog posts

     

    Copyright 1998-2021 Alvin Alexander, alvinalexander.com
    All Rights Reserved.

    A percentage of advertising revenue from
    pages under the /java/jwarehouse URI on this website is
    paid back to open source projects.