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-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.registry;

import org.netbeans.api.registry.Context;
import org.netbeans.api.registry.ContextException;
import org.netbeans.spi.registry.BasicContext;
import org.openide.ErrorManager;
import org.openide.util.TopologicalSortException;
import org.openide.util.Utilities;

import java.util.*;

/** 
 * This class orders context items according to positional attributes
 * and for backward compatibility it also accepts relative ordering
 * attributes. After the relative ordering attrs are removed the
 * ordering functionality in this class can be simplified.
 * 
 * There are also several checks for "ordered" attribute
 * which are commented out till this mechanism gets common.
 *
 * @author copy & pasted from old Datasystems
 */
public class OrderingSupport {

    private static final char SEP = '/';

    public static final OrderingSupport DEFAULT = new OrderingSupport();
    
    private OrderingSupport() {
    }

    /**
     * @return ordered list of binding names and subcontext names.
     *
     */
    public List getOrderedNames(Context ctx) {
        
        // check that context is ordered
        String ordered = ctx.getAttribute(null, "ordered", null);
        if (ordered == null || (!ordered.equals("true"))) {
            // TODO: add this diagnostic later
            // ErrorManager.getDefault().log(ErrorManager.WARNING, "Context "+ctx+" is not marked as ordered.");
        }
        
        List l = getItems(ctx);
        Map constraints = getOrderingConstraints(ctx);
        if (constraints.keySet().size() != 0) {
            try {
                l = Utilities.topologicalSort(l, constraints);
            } catch (TopologicalSortException ex) {
                List corrected = ex.partialSort();
                ErrorManager.getDefault().log(ErrorManager.WARNING, "Note: context [" + ctx + "] cannot be consistently sorted due to ordering conflicts."); // NOI18N
                ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
                ErrorManager.getDefault().log(ErrorManager.WARNING, "Using partial sort: " + corrected); // NOI18N
                l = corrected;
            }
        }
        
        // check for fullorder attribute
        String fullorder = ctx.getAttribute(null, "fullorder", null);
        if (fullorder != null) {
            List list = new ArrayList();
            // ensure that items are returned in specified full order
            // and additional items are left as they are at the end
            StringTokenizer tok = new StringTokenizer(fullorder, ",");
            while (tok.hasMoreTokens()) {
                String token = tok.nextToken();
                if (l.remove(token)) {
                    list.add(token);
                }
            }
            list.addAll(l);
            l = list;
        }
        return l;
    }

    // list all items of the context
    private List getItems(Context ctx) {
        List l = new ArrayList();
        Iterator i = ctx.getBindingNames().iterator();
        while (i.hasNext()) {
            l.add((String)i.next());
        }
        i = ctx.getSubcontextNames().iterator();
        while (i.hasNext()) {
            l.add(((String)i.next())+"/");
        }
        return l;
    }
    
    private Map getOrderingConstraints(Context ctx) {
        Map map = new HashMap();
        try {
            addPositions(map, ctx);
        } catch (ContextException ex) {
            ErrorManager.getDefault().log(ErrorManager.EXCEPTION, ex.toString());
        }
        addPartials(map, ctx);
        return map;
    }

    
    /** 
     * Read old partial ordering attributes. Method updates the passed map.
     *
     * @param m map> where key is 
     * binding name or subcontext name and value is list of
     * binding names or subcontext names which must go after the key.
     */
    private void addPartials(Map m, Context ctx) {
        Iterator i = ctx.getAttributeNames(null).iterator();
        while (i.hasNext()) {
            String attrName = (String)i.next();
            if (attrName.indexOf (SEP) != -1) {
                // TODO: convert bool attr to String in ContextImpl
                String value = ctx.getAttribute(null, attrName, "");
                if (value.equals("true")) {
                    int idx = attrName.indexOf(SEP);
                    String a = attrName.substring(0, idx);
                    String b = attrName.substring(idx + 1);
                    
                    // this might not work in some cases, but this is just backward solution
                    // so I guess it is OK: I expect that file with extension is a binding and
                    // file without extension is subcontext.
                    idx = a.lastIndexOf('.');
                    if (idx != -1) {
                        // probably binding. cut off extension
                        a = a.substring(0, idx);
                    } else {
                        // probably subcontext. append "/"
                        a = a + "/";
                    }
                    idx = b.lastIndexOf('.');
                    if (idx != -1) {
                        // probably binding. cut off extension
                        b = b.substring(0, idx);
                    } else {
                        // probably subcontext. append "/"
                        b = b + "/";
                    }
                    
                    List l = (List)m.get(a);
                    if (l == null) {
                        m.put(a, l = new LinkedList());
                    }
                    l.add(b);
                    
                }
            }
        }
    }

    /** 
     * Read positional ordering attributes. Method updates the passed map.
     *
     * @param m map> where key is 
     * binding name or subcontext name and value is list of
     * binding names or subcontext names which must go after the key.
     */
    private void addPositions(Map m, Context ctx) throws ContextException {
        Map map = new HashMap();
        BasicContext basicCtx = ApiContextFactory.DEFAULT.getBasicContext(ctx);
        Iterator i = ctx.getBindingNames().iterator();
        while (i.hasNext()) {
            String bindingName = (String)i.next();
            String position = ctx.getAttribute(bindingName, "position", null);
            if (position != null) {
                try {
                    Float f = new Float(position);
                    String bnd = (String)map.put(f, bindingName);
                    if (bnd != null) {
                        ErrorManager.getDefault().log(ErrorManager.WARNING, "Ordering Error: Two items in context ["+ctx+
                            "] has the same position ["+position+"]: "+bnd+" "+bindingName);
                    }
                } catch (NumberFormatException ex) {
                    // ok to ignore.
                }
            } else {
                // TODO: add this diagnostic later
                // ErrorManager.getDefault().log(ErrorManager.WARNING, "Binding "+bindingName+" in context "+ctx+" does not have position attribute.");
            }
        }
        i = ctx.getSubcontextNames().iterator();
        while (i.hasNext()) {
            String subcontextName = (String)i.next();
            Context subCtx = ctx.getSubcontext(subcontextName);
            if (subCtx == null) {
                continue;
            }
            String position = subCtx.getAttribute(null, "position", null);
            if (position != null) {
                try {
                    Float f = new Float(position);
                    String sub = (String)map.put(f, subcontextName+"/");
                    if (sub != null) {
                        ErrorManager.getDefault().log(ErrorManager.WARNING, "Ordering Error: Two items in context ["+ctx+
                            "] has the same position ["+position+"]: "+sub+" "+subcontextName);
                    }
                } catch (NumberFormatException ex) {
                    // ok to ignore.
                }
            } else {
                // TODO: add this diagnostic later
                // ErrorManager.getDefault().log(ErrorManager.WARNING, "Subcontext "+subcontextName+" in context "+ctx+" does not have position attribute.");
            }
        }
        List l = new ArrayList(map.keySet());
        Collections.sort(l);
        for (int k=0; k
... 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.