Skip to main content
summaryrefslogblamecommitdiffstats
blob: a15276e70960176aa4d6f7e3b80ae6f8448922b7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

                                                                  

                    






                             


                                            

                                      
                                                             

                                                                               



                                                                                       

                                                                                                         
















                                                                                                    
                        

                                                      

                                                 
     
                          







































                                                                      


















                                                                            
                                                                          














                                                                            
                                                                          


       


                                
       


                               


                                                                                                                                            
                                                                                                                     


                             
                            
           
                                                          
                                             
         
                                                                            



                                    

                                                                                       
                                           

                             
                                                                   


                                                                              

                                                                 


                                                                       

                               


                                                                           
                                                   



                                                                              
                                         






                                                                            
                                     
                      




                             
                            
           

                                                                       
         
                                                                            
                                                                        


                       


                                                                                       
             


                                              
                                               

                                 
                                                                       

                                         
             




                                                 
                                                             

                                                                                                                    
                                                                

                                












                                                                                                                    
             

                           


















                                                                                             

                                                                 

                      


                                                                         















                                                                            

                                                                     






                                                                                             

                                                                             
                                      
                 

                                                                              



                                                                          
                     
                                                                             




                                                                          



                                           

                               








                                                                           
                                                      





                                                                                                                 
                                              
                 










                                                                                
                          








                                                                                



                          



























































                                                                                                  

     
package org.eclipse.jst.jsf.facelet.core.internal.registry.taglib;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.jsf.common.internal.util.JarUtilities;
import org.eclipse.jst.jsf.designtime.internal.resources.IJSFResource;
import org.eclipse.jst.jsf.designtime.internal.resources.IJSFResourceContainer;
import org.eclipse.jst.jsf.designtime.internal.resources.IJSFResourceFragment;
import org.eclipse.jst.jsf.designtime.internal.resources.IJarBasedJSFResource;
import org.eclipse.jst.jsf.designtime.internal.resources.IWorkspaceJSFResourceFragment;
import org.eclipse.jst.jsf.designtime.internal.resources.WorkspaceJSFResourceContainer;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.Listener.TaglibChangedEvent;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.Listener.TaglibChangedEvent.CHANGE_TYPE;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.FaceletTaglibFactory;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.FaceletTaglibTag;

/**
 * A facelet tag record is derived from a JSF locatable resource (ezcomp).
 * 
 * @author cbateman
 * 
 */
public class JSFResourceBasedTagRecord extends FaceletTagRecord
{
    private final List<FaceletTaglibTag> _tags;
    private final String _uri;

    /**
     * @param uri
     * @param tags
     * @param descriptor
     */
    public JSFResourceBasedTagRecord(final String uri,
            final List<FaceletTaglibTag> tags,
            final TagRecordDescriptor descriptor)
    {
        super(descriptor);
        _uri = uri;
        _tags = tags;
    }

    /**
     * 
     */
    private static final long serialVersionUID = 5944923828112777373L;

    public int getNumTags()
    {
        return _tags.size();
    }

    @Override
    public String getURI()
    {
        return _uri;
    }

    @Override
    public FaceletTaglibTag getTag(final String name)
    {
        for (final FaceletTaglibTag tag : _tags)
        {
            if (tag.getTagName().equals(name))
            {
                return tag;
            }
        }
        return null;
    }

    @Override
    public Collection<? extends FaceletTaglibTag> getTags()
    {
        return Collections.unmodifiableCollection(_tags);
    }

    /**
     * Merge my tags with 'withThese'. Tags in my list will be replaced with
     * those in 'withThese' if their names match.
     * 
     * @param withThese
     */
    /* package */JSFResourceBasedTagRecord mergeTags(
            final List<FaceletTaglibTag> withThese)
    {
        final List<FaceletTaglibTag> tags = new ArrayList<FaceletTaglibTag>(
                _tags);
        for (final FaceletTaglibTag mergeTag : withThese)
        {
            final FaceletTaglibTag tag = getTag(mergeTag.getTagName());
            if (tag != null)
            {
                tags.remove(tag);
            }
            tags.add(mergeTag);
        }
        return new JSFResourceBasedTagRecord(_uri, tags, getDescriptor());
    }

    /* package */JSFResourceBasedTagRecord removeTags(
            final List<FaceletTaglibTag> removeThese)
    {
        final List<FaceletTaglibTag> tags = new ArrayList<FaceletTaglibTag>(
                _tags);
        for (final FaceletTaglibTag mergeTag : removeThese)
        {
            final FaceletTaglibTag tag = getTag(mergeTag.getTagName());
            if (tag != null)
            {
                tags.remove(tag);
            }
        }
        return new JSFResourceBasedTagRecord(_uri, tags, getDescriptor());
    }

    /**
     * A builder for tag record.
     * 
     * @author cbateman
     * 
     */
    public static class Builder
    {
        private static final LibEntry WHOLE_LIBRARY = new LibEntry(null);
        private static final JSFResourceBasedTagRecord WHOLE_LIB_RECORD = new JSFResourceBasedTagRecord(null, Collections.EMPTY_LIST, null);
        private final Map<String, LibEntry> _tags = new HashMap<String, LibEntry>();
        private static final String FACELET_FILE_CONTENT_TYPE = "org.eclipse.wst.html.core.htmlsource"; //$NON-NLS-1$

        /**
         * @param jsfResource
         * @param changeType
         */
        public void addTag(final IJSFResource jsfResource,
                final CHANGE_TYPE changeType)
        {
            final String libraryName = jsfResource.getId().getLibraryName();
            if (libraryName == null)
            {
                return;
            }
            final String uri = String.format(
                    "http://java.sun.com/jsf/composite/%s", libraryName); //$NON-NLS-1$
            LibEntry tags = _tags.get(uri);
            if (tags == null)
            {
                tags = new LibEntry(createDescriptor(jsfResource));
                _tags.put(uri, tags);
            }
            final String resourceName = jsfResource.getId().getResourceName();
            final IPath resourceNamePath = new Path(resourceName)
                    .removeFileExtension();
            final FaceletTaglibTag tag = FaceletTaglibFactory.eINSTANCE
                    .createFaceletTaglibTag();
            tag.setTagName(resourceNamePath.toString());
            switch (changeType)
            {
                case ADDED:
                case CHANGED:
                    // only add to the list on a add/change if the resource
                    // exists and is the right type
                    if (jsfResource.isAccessible()
                            && jsfResource
                                    .isContentType(FACELET_FILE_CONTENT_TYPE))
                    {
                        tags.addTag(tag);
                    }
                break;
                case REMOVED:
                    // add all comers to the remove list. There will only be
                    // removal
                    // on merge if ADDED/CHANGED path decided they should be
                    // there.
                    tags.addTag(tag);
                break;
            }
        }

        /**
         * @param jsfResource
         * @param changeType
         */
        public void addLibrary(final IJSFResourceContainer jsfResource,
                final CHANGE_TYPE changeType)
        {
            final String libraryName = jsfResource.getId().getLibraryName();
            if (libraryName == null || libraryName.trim().length() == 0)
            {
                return;
            }
            final String uri = String.format(
                    "http://java.sun.com/jsf/composite/%s", libraryName); //$NON-NLS-1$
            if (changeType == CHANGE_TYPE.REMOVED)
            {
                _tags.put(uri, WHOLE_LIBRARY);
            } else
            {
                LibEntry tags = _tags.get(uri);
                if (tags == null)
                {
                    tags = new LibEntry(createDescriptor(jsfResource));
                    _tags.put(uri, tags);
                }
            }
        }

        /**
         * @return the built list of tag records.
         */
        public Map<String, JSFResourceBasedTagRecord> build()
        {
            final Map<String, JSFResourceBasedTagRecord> records = new HashMap<String, JSFResourceBasedTagRecord>();
            for (final Map.Entry<String, LibEntry> entry : _tags
                    .entrySet())
            {
                if (entry.getValue() == WHOLE_LIBRARY)
                {
                    records.put(entry.getKey(), WHOLE_LIB_RECORD);
                }
                else
                {
                    final String uri = entry.getKey();
                    final List<FaceletTaglibTag> tags = new ArrayList<FaceletTaglibTag>(entry.getValue().getTags());
                    final TagRecordDescriptor descriptor = entry.getValue().getDescriptor();
                    final JSFResourceBasedTagRecord newRecord = new JSFResourceBasedTagRecord(
                            uri, tags, descriptor);
                    records.put(entry.getKey(), newRecord);
                }
            }
            return records;
        }

        /**
         * @param locator
         * @param records
         * @return a list of taglib change events that reflect what will happen
         *         when my tags are merged into the map 'records'.
         */
        public List<TaglibChangedEvent> createMerge(
                final AbstractFaceletTaglibLocator locator,
                final Map<String, JSFResourceBasedTagRecord> records)
        {
            final Map<String, JSFResourceBasedTagRecord> newRecords = build();
            final List<TaglibChangedEvent> mergeEvents = new ArrayList<TaglibChangedEvent>();
            for (final Map.Entry<String, JSFResourceBasedTagRecord> entry : newRecords
                    .entrySet())
            {
                TaglibChangedEvent event = null;
                if (!records.containsKey(entry.getKey()))
                {
                    event = new TaglibChangedEvent(locator, null,
                            entry.getValue(), CHANGE_TYPE.ADDED);
                } else
                {
                    final JSFResourceBasedTagRecord oldRecord = records
                            .get(entry.getKey());
                    final JSFResourceBasedTagRecord newRecord = oldRecord
                            .mergeTags(entry.getValue()._tags);
                    event = new TaglibChangedEvent(locator, oldRecord,
                            newRecord, CHANGE_TYPE.CHANGED);
                }
                mergeEvents.add(event);
            }
            return mergeEvents;
        }

        /**
         * @param locator
         * @param records
         * @return a list of change events that will result from removing my
         *         _tags from records.
         */
        public List<TaglibChangedEvent> createRemove(
                final AbstractFaceletTaglibLocator locator,
                final Map<String, JSFResourceBasedTagRecord> records)
        {
            final Map<String, JSFResourceBasedTagRecord> newRecords = build();
            final List<TaglibChangedEvent> mergeEvents = new ArrayList<TaglibChangedEvent>();
            for (final Map.Entry<String, JSFResourceBasedTagRecord> entry : newRecords
                    .entrySet())
            {
                TaglibChangedEvent event = null;
                final JSFResourceBasedTagRecord oldRecord = records.get(entry
                        .getKey());
                if (oldRecord != null)
                {
                    final JSFResourceBasedTagRecord record = entry.getValue();
                    if (record == WHOLE_LIB_RECORD)
                    {
                        event = new TaglibChangedEvent(locator, oldRecord,
                                null, CHANGE_TYPE.REMOVED);
                    } else
                    {
                        final JSFResourceBasedTagRecord newRecord = oldRecord
                                .removeTags(entry.getValue()._tags);
                        event = new TaglibChangedEvent(locator, oldRecord,
                                newRecord, CHANGE_TYPE.CHANGED);
                    }
                }
                if (event != null)
                {
                    mergeEvents.add(event);
                }
            }
            return mergeEvents;
        }

        /**
         * @param events
         * @param withThese
         * @return a new merged map that contains withThese plus everything
         *         here.
         */
        public Map<String, JSFResourceBasedTagRecord> merge(
                final List<TaglibChangedEvent> events,
                final Map<String, JSFResourceBasedTagRecord> withThese)
        {
            final Map<String, JSFResourceBasedTagRecord> newMap = new HashMap<String, JSFResourceBasedTagRecord>(
                    withThese);
            for (final TaglibChangedEvent event : events)
            {
                switch (event.getChangeType())
                {
                    case ADDED:
                    case CHANGED:
                    {
                        final IFaceletTagRecord newRecord = event.getNewValue();
                        // doubles as null check
                        if (newRecord instanceof JSFResourceBasedTagRecord)
                        {
                            newMap.put(newRecord.getURI(),
                                    (JSFResourceBasedTagRecord) newRecord);
                        }
                    }
                    break;
                    case REMOVED:
                    {
                        final IFaceletTagRecord oldRecord = event.getOldValue();
                        if (oldRecord != null)
                        {
                            newMap.remove(oldRecord.getURI());
                        }
                    }
                    break;
                }
            }
            return newMap;
        }

        private TagRecordDescriptor createDescriptor(final IJSFResourceFragment resource)
        {
            if (resource instanceof IWorkspaceJSFResourceFragment)
            {
                if (resource instanceof WorkspaceJSFResourceContainer)
                {
                    final IResource res = ((WorkspaceJSFResourceContainer)resource).getResource();
                    return new WorkspaceTagRecordDescriptor((IFolder) res);
                }
                final IResource res = ((IWorkspaceJSFResourceFragment) resource)
                        .getResource();
                return new WorkspaceTagRecordDescriptor((IFile) res);
            } else if (resource instanceof IJarBasedJSFResource)
            {
                final URL jarURL = ((IJarBasedJSFResource) resource)
                        .getJarURL();
                final File file = JarUtilities.INSTANCE.getFile(jarURL);
                if (file != null)
                {
                    final String absolutePath = file.getAbsolutePath();
                    final String jarEntryName = ((IJarBasedJSFResource) resource)
                            .getJarEntryName();
                    return new JarTagRecordDescriptor(new Path(absolutePath),
                            jarEntryName);
                }
            }
            return null;
        }

        private static class LibEntry
        {
            private final TagRecordDescriptor _descriptor;
            private final List<FaceletTaglibTag> _tags;

            /**
             * @param descriptor
             */
            public LibEntry(final TagRecordDescriptor descriptor)
            {
                super();
                _descriptor = descriptor;
                _tags = new ArrayList<FaceletTaglibTag>();
            }

            public TagRecordDescriptor getDescriptor()
            {
                return _descriptor;
            }

            public void addTag(final FaceletTaglibTag tag)
            {
                _tags.add(tag);
            }

            public List<FaceletTaglibTag> getTags()
            {
                return Collections.unmodifiableList(_tags);
            }
        }
    }
}

Back to the top