Création d'une classe de filtre de résolution de page de contenu

Un filtre de résolution de page de contenu permet de personnaliser le comportement de la chaîne de filtres de résolution de page de contenu. Cette méthode permet d'adapter la réponse à une demande de contenu Web de plusieurs façons, notamment en remplaçant l'objet de contenu affiché ou la page de portail utilisée pour afficher un objet de contenu dans l'afficheur de contenu Web.

Pourquoi et quand exécuter cette tâche

La chaîne de filtres de résolution de page de contenu se compose de filtres qui reposent sur le modèle de conception de filtre d'interception, qui fournit un mécanisme d'interception de demande et de manipulation de la demande et de sa réponse. Utilisée avec des demandes de contenu Web, la chaîne de filtres de résolution de page de contenu comporte des filtres par défaut qui traitent les paramètres d'URL contenus dans la demande de contenu Web puis identifient la page de portail qui comporte une association de contenu Web correspondante. Les filtres par défaut se trouvent à la fin de la chaîne de filtres.

Vous pouvez personnaliser la chaîne de filtres de résolution de page de contenu par défaut en créant des filtres personnalisés qui sont enregistrés dans le portail via la structure de plug-ins Eclipse dont l'ID d'extension est com.ibm.workplace.wcm.api.ContentPageResolutionFilter. Une valeur de poids associée à chaque filtre spécifie la séquence de filtres dans la chaîne de filtres. Pour insérer des filtres personnalisés dans la chaîne de filtres avant les filtres par défaut, vous pouvez utiliser l'attribut weight dans le fichier plugin.xml. Si l'attribut weight n'est pas spécifié, la séquence de filtres est déterminée par la méthode getFilterChainWeight de chaque filtre personnalisé.

Les filtres personnalisés peuvent effectuer diverses actions :
  • modifier les paramètres avant l'appel des filtres par défaut,
  • modifier le résultat des filtres par défaut,
  • traiter les exceptions générées par les filtres par défaut,
  • Déterminer si les filtres par défaut sont démarrés.
  • modifier le chemin d'accès au contenu qui est utilisé comme entrée pour les filtres par défaut,
  • définir explicitement une page cible pour l'affichage du contenu,
  • Identifier la page de contenu Web utilisée, si les filtres par défaut trouvent plusieurs pages de contenu Web correspondantes pour la demande.
  • modifier la sélection du modèle de présentation,
  • définir les codes d'état des réponses HTTP,
  • envoyer les redirections aux ressources Web externes.

Pour pouvoir utiliser un filtre de résolution de page de contenu, vous devez créer une classe de filtre de résolution de page de contenu puis enregistrer le filtre en le déployant sur le serveur.

Procédure

  1. Créez une classe java qui implémente l'interface com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter. Cette classe peut implémenter les méthodes suivantes :
    public int getFilterChainWeight() {}
    Cette méthode renvoie la pondération qui est appliquée aux éléments de filtre de résolution de page de contenu dans la chaîne de filtres. Plus la pondération est faible plus le filtre est inséré tôt dans la chaîne. Si le paramètre weight est défini dans le fichier plugin.xml, cette valeur remplace la valeur qui est renvoyée par cette méthode.
    public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) {}
    Cette méthode est démarrée lors du traitement ContentPageResolution. Le paramètre response permet de modifier l'objet de contenu affiché, la page de portail sur laquelle le contenu est affiché, et le modèle de présentation utilisé pour afficher l'objet de contenu. La demande étend l'interface de résolution avec une méthode supplémentaire qui extrait l'objet de contenu traité. La chaîne de filtres contient les filtres suivants pouvant être démarrés si nécessaire.

    Consultez la documentation Javadoc pour plus d'informations. The Javadoc files for Web Content Manager are in the PortalServer_root/doc/Javadoc/spi_docs/com/ibm/workplace/wcm directory.

  2. Un fichier plugin.xml est requis, que le déploiement soit effectué via un fichier WAR, EAR ou JAR. Si vous effectuez le déploiement via une application dans un fichier WAR ou EAR, vous devez inclure le fichier plugin.xml dans le dossier "WEB-INF" de l'application. Lorsque vous utilisez un fichier JAR, vous devez inclure le fichier plugin.xml à la racine de ce fichier JAR.
    <?xml version="1.0" encoding="UTF-8"?>
    <plugin id="com.example"
           name="Sample Content Page Resolution Filter"
           version="1.0.0"
           provider-name="IBM">
           
     <extension
        point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter"
        id="SampleContentPageResolutionFilter">
        <provider class="com.example.SampleContentPageResolutionFilter"
                  weight="1"/>
     </extension>
    
    </plugin>
    Lorsque vous créez des plug-ins, tenez compte des points suivants :
    • Chaque plug-in est représenté par une balise <extension> unique.
    • La valeur de l'attribut du point d'extension doit être com.ibm.workplace.wcm.api.ContentPageResolutionFilter.
    • Entrez l'ID de votre choix.
    • Spécifiez la classe de filtre pour votre plug-in.
    • Le paramètre weight remplace la valeur de la méthode getFilterChainWeight.
    Naming conventions :
    Si vous créez une nouvelle application de plug-in associée aux mêmes nom et ID qu'un plug-in existant, le nouveau plug-in risque de remplacer le premier. Lorsque vous créez des applications de plug-in, vérifiez que les éléments suivants sont uniques sur votre système :
    • L'ID plug-in, le nom de plug-in et l'ID extension du fichier plugin.xml.
    • le chemin et le nom de classe qualifié complet de toutes les classes dans l'application,
    • le chemin d'accès aux fichiers de l'application.

Exemples

  • L'exemple LocaleDependantSelectionFilter effectue la résolution de page par défaut et sélectionne une page cible à partir des pages candidates, selon l'environnement local de l'utilisateur.
    package com.ibm.workplace.wcm.extension.resolution;
    
    import java.util.List;
    import java.util.Locale;
    
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import com.ibm.portal.ObjectID;
    import com.ibm.portal.model.CorLocalizedContextHome;
    import com.ibm.portal.model.LocalizedContext;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse;
    import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException;
    
    public class LocaleDependantSelectionFilter implements ContentPageResolutionFilter
    {
       CorLocalizedContextHome localizedContextHome;
       
       public LocaleDependantSelectionFilter()
       {
          try
          {
             InitialContext ctx = new InitialContext();
             localizedContextHome = (CorLocalizedContextHome) ctx.lookup(CorLocalizedContextHome.JNDI_NAME);   
          }
          catch(NamingException e)
          {
             e.printStackTrace();
          }
       }
    
       public int getFilterChainWeight()
       {
          return 2;
       }
    
       public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain)
             throws ContentPageResolutionException
       {
          // do standard resolution first
          chain.resolve(request, response);
          
          // check if more than one candidate pages
          List<ObjectID> candidates = response.getCandidatePageIds();
          if (candidates.size() > 1)
          {
             LocalizedContext context = localizedContextHome.getLocalizedContext(request.getContext());
             Locale locale = context.getPreferredSupportedLocale();
             String lang = locale.getLanguage();
             // find page with matching unique name
             for (ObjectID pageId : candidates)
             {
                if (pageId.getUniqueName().endsWith("." + lang))
                {
                   response.setPageID(pageId);
                   break;
                }
             }
          }
       }
    }
  • L'exemple ChangeContentPathFilter se substitue au chemin du contenu qui s'affiche mais effectue la résolution des pages sur le contenu demandé initialement.
    package com.ibm.workplace.wcm.extension.resolution;
    
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse;
    import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException;
    
    public class ChangeContentPathFilter implements ContentPageResolutionFilter
    {
       public int getFilterChainWeight()
       {
          return 3;
       }
    
       public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain)
             throws ContentPageResolutionException
       {
          // resolve page using requested content 
          chain.resolve(request, response);
          
          // but instead of england render UK
          if ("countries/world/europe/england".equals(response.getContentPath()))
          {
             response.setContentPath("countries/world/europe/uk");
          }
       }
    }
  • L'exemple ResolveToSpecificPageFilter effectue une résolution sur une page spécifique. Aucune résolution par défaut n'est effectuée dans ce cas.
    package com.ibm.workplace.wcm.extension.resolution;
    import java.util.Arrays;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import com.ibm.portal.ObjectID;
    import com.ibm.portal.identification.Identification;
    import com.ibm.portal.serialize.SerializationException;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse;
    import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException;
    
    public class ResolveToSpecificPageFilter implements ContentPageResolutionFilter
    {
       private Identification identification;
       
       public ResolveToSpecificPageFilter()
       {
          try
          {
              InitialContext ctx = new InitialContext();
              identification = (Identification) ctx.lookup("portal:service/Identification");
          }
          catch (NamingException nx)
          {
              nx.printStackTrace();
          }
       }
    
       public int getFilterChainWeight()
       {
          return 4;
          }
    
    
     public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException
    
     {
    
          try 
          {
          // always resolve to page with unique name my.default.page
          ObjectID pageId = identification.deserialize("my.default.page");
          response.setPageID(pageId);
          response.setCandidatePageIds(Arrays.asList(new ObjectID[]{pageId}));
          } 
          catch (SerializationException e)
          {
              throw new ContentPageResolutionException(e);
          }
      }
    }
  • L'exemple SetResponseCodePageResolutionFilter recherche l'objet de contenu Web demandé. S'il n'existe pas, le code génère une exception qui envoie un code d'état de réponse HTTP 404 (Introuvable). Si le contenu existe, la résolution est déléguée à d'autres filtres de la chaîne.
    package com.ibm.workplace.wcm.extension.resolution;
    
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Locale;
    import java.util.Set;
    import javax.servlet.http.HttpServletResponse;
    import com.ibm.portal.ListModel;
    import com.ibm.portal.LocalizedStatus;
    import com.ibm.portal.ModelException;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse;
    import com.ibm.workplace.wcm.api.extensions.resolution.ResolvedItem;
    import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException;
    
    public class SetResponseCodePageResolutionFilter implements ContentPageResolutionFilter
    
    {
    	 public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException
      {
          if (!itemExists(request.getItem()))
          {
    			       // send 404
    			       throw new ContentPageResolutionException(new ContentNotFoundException());
          } 
    		   else
    		   {
    			      // forward to the chain if the web content exists
    			      chain.resolve(request, response);
    		   }
    	}
    
    	private boolean itemExists(ResolvedItem item)
    	{
           		return (item.getItemID() != null) && (item.getItemPath() != null);
    	}
    	public int getFilterChainWeight()
    	{
    	        	return 1;
    	}
    
    	private static class ContentNotFoundException extends Exception implements LocalizedStatus
    	{
           		private static final long serialVersionUID = 70L;
           		private static final Set<Locale> SUPPORTED_LOCALES = new HashSet<Locale>(Arrays.asList(new Locale[] { Locale.ENGLISH }));
     		private static final String MESSAGE = "The requested web content does not exist"; 
    
     		public ContentNotFoundException()
      		{ 			
                  super(MESSAGE);  		
         } 		 		
         
         public int getStatus()
      		{ 			
                 return HttpServletResponse.SC_NOT_FOUND;
      		}  		
         public String getTitle(Locale locale)
      		{  			
                  return MESSAGE; 		
         }   		
         public String getDescription(Locale locale)  		
         {  			
                  return MESSAGE;  		
         }  		
         public ListModel<Locale> getLocales()  		
         { 			
                  return new ListModel<Locale>()
                  {  				
                          public Iterator<Locale> iterator() throws ModelException
                          {
                                   return SUPPORTED_LOCALES.iterator();
                          }
                  };
        	}
       }
      }
  • L'exemple SendRedirectPageResolutionFilter recherche l'objet de contenu Web demandé. Si le contenu n'existe pas, le code envoie un réacheminement vers http://www.ibm.com. Si le contenu existe, la résolution est déléguée à d'autres filtres de la chaîne.
    package com.ibm.workplace.wcm.extension.resolution;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.net.URLEncoder;
    import com.ibm.portal.resolver.exceptions.ResolutionException;
    import com.ibm.portal.resolver.helper.CORResolutionService;
    import com.ibm.portal.state.exceptions.StateException;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest;
    import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse;
    import com.ibm.workplace.wcm.api.extensions.resolution.ResolvedItem;
    import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException;
    
    public class SendRedirectPageResolutionFilter implements ContentPageResolutionFilter
    {
    	// the URL to redirect to
    	private static final String URL = "http://www.ibm.com";
    
    	public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException
    	{
    		if (!itemExists(request.getItem()))
    		{
    			try
    			{
    				// encode to URL, this is important to prevent that the ':'
    				// character appears in the path
    				String encodedURL = URLEncoder.encode(URL, "UTF-8");
    				final URI redirectURI = new URI(com.ibm.portal.resolver.Constants.SCHEME_REDIRECT, encodedURL, null);
    				CORResolutionService.SINGLETON.resolve(request.getResolved(), redirectURI, request.getVerb(), request.getResolutionParameters(), request.getAcceptedBindings(),request.getContext());
    			} catch (UnsupportedEncodingException uenc)
    			{
    				// should never happens as long as UTF-8 is supported
    				throw new ContentPageResolutionException(uenc);
    			} catch (URISyntaxException e)
    			{
    				throw new ContentPageResolutionException(e);
    			} catch (StateException e)
    			{
    				throw new ContentPageResolutionException(e);
    			} catch (ResolutionException e)
    			{
    				// do not catch the resolution exception
    				// as this is used internally to trigger the redirect
    				throw new ContentPageResolutionException(e);
    			}
    		} else
    		{
    			chain.resolve(request, response);
    		}
    	}
    
    	private boolean itemExists(ResolvedItem item)
    	{
    		return (item.getItemID() != null) && (item.getItemPath() != null);
    	}
    
    	public int getFilterChainWeight() 
    	{
    		return 1;
    	}
    }
  • L'exemple suivant fournit le fichier plugin.xml qui enregistre les exemples de filtre précédents.

    L'enregistrement de tous ces filtres sur un même système n'est pas recommandé. Les filtres effectuent des opérations qui se chevauchent et, dans certains cas, sont mutuellement exclusifs. Pour utiliser l'un des filtres sur votre système, supprimez les autres filtres inutilisés dans le fichier plugin.xml avant de déployer ce dernier.

    <?xml version="1.0" encoding="UTF-8"?>
    <?eclipse version="3.0"?>
    <plugin
       id="com.ibm.workplace.wcm.extension.resolution"
       name="Content Page Resolution Filter"
       version="1.0.0"
       provider-name="IBM">
       
       <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter"
           id="SendRedirectPageResolutionFilter">
           <provider class="com.ibm.workplace.wcm.extension.resolution.SendRedirectPageResolutionFilter"
                    weight="1"/>
       </extension>
    
       <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter"
            id="SetResponseCodePageResolutionFilter">
            <provider class="com.ibm.workplace.wcm.extension.resolution.SetResponseCodePageResolutionFilter"
                    weight="1"/>
       </extension>
    
       <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter"
          id="LocaleDependantSelectionFilter">
          <provider class="com.ibm.workplace.wcm.extension.resolution.LocaleDependantSelectionFilter"
                    weight="2"/>
        </extension>
    
       <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter"
          id="ChangeContentPathFilter">
          <provider class="com.ibm.workplace.wcm.extension.resolution.ChangeContentPathFilter"
                    weight="3"/>
        </extension>
    
       <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter"
          id="ResolveToSpecificPageFilter">
          <provider class="com.ibm.workplace.wcm.extension.resolution.ResolveToSpecificPageFilter"
                    weight="4"/>
        </extension>
    </plugin>