svn commit: r736668 - in /lenya/trunk/src: modules-core/sitemanagement/usecases/tab/ modules/sitetree/ modules/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/ modules/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/ modules/sitet...

[email protected]
Newsgroups gmane.comp.cms.lenya.cvs
Message-ID <[email protected]>
Author: andreas
Date: Thu Jan 22 07:16:06 2009
New Revision: 736668

URL: http://svn.apache.org/viewvc?rev=736668&view=rev
Log:
Fixed AccessControlSitetreeTransformer, use /modules/sitetree URL for sitetree fragments so that users without permissions on the actual pages can get the respective sitetree fragments.

Modified:
    lenya/trunk/src/modules-core/sitemanagement/usecases/tab/sitetree.jx
    lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java
    lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java
    lenya/trunk/src/modules/sitetree/resources/javascript/lenyatree.js
    lenya/trunk/src/modules/sitetree/resources/javascript/navtree.js
    lenya/trunk/src/modules/sitetree/sitemap.xmap

Modified: lenya/trunk/src/modules-core/sitemanagement/usecases/tab/sitetree.jx
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/sitemanagement/usecases/tab/sitetree.jx?rev=736668&r1=736667&r2=736668&view=diff
==============================================================================
--- lenya/trunk/src/modules-core/sitemanagement/usecases/tab/sitetree.jx (original)
+++ lenya/trunk/src/modules-core/sitemanagement/usecases/tab/sitetree.jx Thu Jan 22 07:16:06 2009
@@ -70,7 +70,6 @@
       <div id="tree">
         <script type="text/javascript">
           WEBAPP_BASE_PATH = '<proxy:url href="/"/>';
-          AREA_BASE_PATH = '<proxy:url href="/${publicationId}/${area}"/>';
           USECASE = '${usecase.getName()}';
           
           PUBLICATION_ID = '<jx:out value="${publicationId}"/>';
@@ -98,7 +97,7 @@
           </jx:choose>
           
           ALL_AREAS = 'authoring,trash,archive';
-          PIPELINE_PATH = '/sitetree-fragment.xml';
+          PIPELINE_PATH = 'modules/sitetree/sitetree-fragment.xml';
           SHOW_LOADING_HINT = true;
           SHOW_ICONS = true;
           

Modified: lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java?rev=736668&r1=736667&r2=736668&view=diff
==============================================================================
--- lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java (original)
+++ lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/generation/SitetreeFragmentGenerator.java Thu Jan 22 07:16:06 2009
@@ -93,31 +93,31 @@
     protected static final String PARAM_AREAS = "areas";
 
     /** The URI of the namespace of this generator. */
-    protected static final String URI = "http://apache.org/cocoon/lenya/sitetree/1.0";
-    protected static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
+    public static final String URI = "http://apache.org/cocoon/lenya/sitetree/1.0";
+    public static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
 
     /** The namespace prefix for this namespace. */
     protected static final String PREFIX = "site";
     protected static final String XML_PREFIX = "xml";
 
-    protected static final String NODE_NODE = "node";
-    protected static final String NODE_LABEL = "label";
-    protected static final String NODE_SITE = "site";
-    protected static final String NODE_FRAGMENT = "fragment";
-
-    protected static final String ATTR_ID = "id";
-    protected static final String ATTR_FOLDER = "folder";
-    protected static final String ATTR_AREA = "area";
-    protected static final String ATTR_PUBLICATION = "publication";
-    protected static final String ATTR_LABEL = "label";
-    protected static final String ATTR_VISIBLEINNAV = "visibleinnav";
-    protected static final String ATTR_LINK = "link";
-    protected static final String ATTR_BASE = "base";
-    protected static final String ATTR_SUFFIX = "suffix";
-    protected static final String ATTR_HREF = "href";
-    protected static final String ATTR_UUID = "uuid";
-    protected static final String ATTR_LANG = "lang";
-    protected static final String ATTR_TYPE = "mimetype";
+    public static final String NODE_NODE = "node";
+    public static final String NODE_LABEL = "label";
+    public static final String NODE_SITE = "site";
+    public static final String NODE_FRAGMENT = "fragment";
+
+    public static final String ATTR_ID = "id";
+    public static final String ATTR_FOLDER = "folder";
+    public static final String ATTR_AREA = "area";
+    public static final String ATTR_PUBLICATION = "publication";
+    public static final String ATTR_LABEL = "label";
+    public static final String ATTR_VISIBLEINNAV = "visibleinnav";
+    public static final String ATTR_LINK = "link";
+    public static final String ATTR_BASE = "base";
+    public static final String ATTR_SUFFIX = "suffix";
+    public static final String ATTR_HREF = "href";
+    public static final String ATTR_UUID = "uuid";
+    public static final String ATTR_LANG = "lang";
+    public static final String ATTR_TYPE = "mimetype";
 
     /**
      * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,

Modified: lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java?rev=736668&r1=736667&r2=736668&view=diff
==============================================================================
--- lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java (original)
+++ lenya/trunk/src/modules/sitetree/java/src/org/apache/lenya/cms/cocoon/transformation/AccessControlSitetreeTransformer.java Thu Jan 22 07:16:06 2009
@@ -21,10 +21,11 @@
 package org.apache.lenya.cms.cocoon.transformation;
 
 import java.io.IOException;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Stack;
 
 import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.parameters.ParameterException;
 import org.apache.avalon.framework.parameters.Parameters;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceSelector;
@@ -38,8 +39,8 @@
 import org.apache.lenya.ac.Identity;
 import org.apache.lenya.ac.PolicyManager;
 import org.apache.lenya.ac.Role;
-import org.apache.lenya.cms.site.tree.DefaultSiteTree;
-import org.apache.lenya.cms.site.tree.SiteTreeNodeImpl;
+import org.apache.lenya.cms.cocoon.generation.SitetreeFragmentGenerator;
+import org.apache.lenya.util.Assert;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
@@ -54,22 +55,17 @@
      * <code>ATTRIBUTE_PROTECTED</code> The attribute for protected
      */
     public static final String ATTRIBUTE_PROTECTED = "protected";
-    /**
-     * <code>PARAMETER_PUBLICATION_ID</code> The publication id parameter
-     */
-    public static final String PARAMETER_PUBLICATION_ID = "publication-id";
-    /**
-     * <code>PARAMETER_AREA</code> The area parameter
-     */
-    public static final String PARAMETER_AREA = "area";
 
-    private String documentId;
     private ServiceSelector serviceSelector;
     private PolicyManager policyManager;
     private AccessControllerResolver acResolver;
     private AccreditableManager accreditableManager;
     private Identity identity;
-    private String urlPrefix;
+
+    private String pubId;
+    private String area;
+    private String basePath;
+    private Stack pathElements = new Stack();
 
     /**
      * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,
@@ -86,40 +82,24 @@
         this.identity = Identity.getIdentity(this.request.getSession(false));
 
         try {
-            String publicationId = par.getParameter(PARAMETER_PUBLICATION_ID);
-            String area = par.getParameter(PARAMETER_AREA);
 
             if (getLogger().isDebugEnabled()) {
                 getLogger().debug("Setting up transformer");
                 getLogger().debug("    Identity:       [" + this.identity + "]");
-                getLogger().debug("    Publication ID: [" + publicationId + "]");
-                getLogger().debug("    Area:           [" + area + "]");
             }
 
-            this.urlPrefix = "/" + publicationId + "/" + area;
+            this.serviceSelector = (ServiceSelector) this.manager
+                    .lookup(AccessControllerResolver.ROLE + "Selector");
 
-            this.serviceSelector = (ServiceSelector) this.manager.lookup(AccessControllerResolver.ROLE
-                    + "Selector");
-
-            this.acResolver = (AccessControllerResolver) this.serviceSelector.select(AccessControllerResolver.DEFAULT_RESOLVER);
+            this.acResolver = (AccessControllerResolver) this.serviceSelector
+                    .select(AccessControllerResolver.DEFAULT_RESOLVER);
 
             if (getLogger().isDebugEnabled()) {
                 getLogger().debug("    Resolved AC resolver [" + this.acResolver + "]");
             }
 
-            AccessController accessController = this.acResolver.resolveAccessController(this.urlPrefix);
-            this.accreditableManager = accessController.getAccreditableManager();
-            this.policyManager = accessController.getPolicyManager();
-
-            if (getLogger().isDebugEnabled()) {
-                getLogger().debug("    Using policy manager [" + this.policyManager + "]");
-            }
-        } catch (final ParameterException e) {
-            throw new ProcessingException(e);
         } catch (final ServiceException e) {
             throw new ProcessingException(e);
-        } catch (final AccessControlException e) {
-            throw new ProcessingException(e);
         }
 
     }
@@ -128,9 +108,6 @@
      * @see org.apache.avalon.framework.activity.Disposable#dispose()
      */
     public void dispose() {
-        if (getLogger().isDebugEnabled()) {
-            getLogger().debug("Disposing transformer");
-        }
         if (this.serviceSelector != null) {
             if (this.acResolver != null) {
                 this.serviceSelector.release(this.acResolver);
@@ -144,7 +121,6 @@
      */
     public void startDocument() throws SAXException {
         super.startDocument();
-        this.documentId = "";
     }
 
     /**
@@ -157,39 +133,41 @@
 
         Attributes attributes = attr;
 
-        if (isFragmentNode(uri, localName)) {
-            String area = attr.getValue("area"); // FIXME: don't hardcode
-            String base = attr.getValue("base");
-            if (area != null && base != null) {
-                this.documentId = "/" + area + base;
-            }
-        }
-        if (isNode(uri, localName)) {
-            String id = attr.getValue(SiteTreeNodeImpl.ID_ATTRIBUTE_NAME);
-            if (id != null) {
-                this.documentId += "/" + id;
-            }
+        if (isFragmentElement(uri, localName)) {
+            this.pubId = attr.getValue(SitetreeFragmentGenerator.ATTR_PUBLICATION);
+            Assert.notNull("publication attribute", this.pubId);
 
-            if (getLogger().isDebugEnabled()) {
-                getLogger().debug("Checking node");
-                getLogger().debug("    Document ID: [" + this.documentId + "]");
-                getLogger().debug("    URL:         [" + this.urlPrefix + this.documentId + "]");
+            String area = attr.getValue("area");
+            if (area != null) {
+                this.area = area;
             }
 
-            try {
-                String url = this.urlPrefix + this.documentId;
-                Role[] roles = this.policyManager.getGrantedRoles(this.accreditableManager, this.identity, url);
+            String basePath = attr.getValue(SitetreeFragmentGenerator.ATTR_BASE);
+            this.basePath = basePath == null ? "" : basePath;
 
-                getLogger().debug("    Roles:       [" + roles.length + "]");
+            try {
+                AccessController accessController = this.acResolver.resolveAccessController("/"
+                        + this.pubId + "/");
+                this.accreditableManager = accessController.getAccreditableManager();
+                this.policyManager = accessController.getPolicyManager();
+            } catch (AccessControlException e) {
+                throw new SAXException(e);
+            }
 
-                if (roles.length == 0) {
-                    getLogger().debug("    Adding attribute [protected='true']");
+        } else if (isSiteElement(uri, localName)) {
+            this.area = attr.getValue("area");
+            Assert.notNull("area attribute", this.area);
+        } else if (isNodeElement(uri, localName)) {
+            String id = attr.getValue(SitetreeFragmentGenerator.ATTR_ID);
+            Assert.notNull("id attribute", id);
+            this.pathElements.push(id);
 
+            try {
+                Role[] roles = this.policyManager.getGrantedRoles(this.accreditableManager,
+                        this.identity, getUrl());
+                if (roles.length == 0 || roles.length == 1 && roles[0].getId().equals("session")) {
                     AttributesImpl attributesImpl = new AttributesImpl(attributes);
-                    attributesImpl.addAttribute("",
-                            ATTRIBUTE_PROTECTED,
-                            ATTRIBUTE_PROTECTED,
-                            "",
+                    attributesImpl.addAttribute("", ATTRIBUTE_PROTECTED, ATTRIBUTE_PROTECTED, "",
                             Boolean.toString(true));
                     attributes = attributesImpl;
                 }
@@ -201,15 +179,26 @@
         super.startElement(uri, localName, raw, attributes);
     }
 
+    protected String getUrl() {
+        Assert.notNull("pub ID", this.pubId);
+        Assert.notNull("area", this.area);
+        Assert.notNull("base path", this.basePath);
+        StringBuffer path = new StringBuffer();
+        for (Iterator i = this.pathElements.iterator(); i.hasNext();) {
+            path.append("/").append(i.next());
+        }
+        return "/" + this.pubId + "/" + this.area + this.basePath + path.toString();
+    }
+
     /**
      * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String,
      *      java.lang.String)
      */
     public void endElement(String uri, String localName, String raw) throws SAXException {
-        super.endElement(uri, localName, raw);
-        if (isNode(uri, localName) && this.documentId.length() > 0) {
-            this.documentId = this.documentId.substring(0, this.documentId.lastIndexOf("/"));
+        if (isNodeElement(uri, localName)) {
+            this.pathElements.pop();
         }
+        super.endElement(uri, localName, raw);
     }
 
     /**
@@ -218,9 +207,9 @@
      * @param localName The local name.
      * @return A boolean value.
      */
-    protected boolean isNode(String uri, String localName) {
-        return uri.equals(DefaultSiteTree.NAMESPACE_URI)
-                && (localName.equals(SiteTreeNodeImpl.NODE_NAME) || localName.equals("site"));
+    protected boolean isNodeElement(String uri, String localName) {
+        return uri.equals(SitetreeFragmentGenerator.URI)
+                && localName.equals(SitetreeFragmentGenerator.NODE_NODE);
     }
 
     /**
@@ -229,8 +218,27 @@
      * @param localName The local name.
      * @return A boolean value.
      */
-    protected boolean isFragmentNode(String uri, String localName) {
-        return uri.equals(DefaultSiteTree.NAMESPACE_URI) && (localName.equals("fragment"));
+    protected boolean isFragmentElement(String uri, String localName) {
+        return uri.equals(SitetreeFragmentGenerator.URI)
+                && localName.equals(SitetreeFragmentGenerator.NODE_FRAGMENT);
+    }
+
+    /**
+     * Returns if an element represents a site node.
+     * @param uri The namespace URI.
+     * @param localName The local name.
+     * @return A boolean value.
+     */
+    protected boolean isSiteElement(String uri, String localName) {
+        return uri.equals(SitetreeFragmentGenerator.URI)
+                && localName.equals(SitetreeFragmentGenerator.NODE_SITE);
+    }
+
+    public void recycle() {
+        super.recycle();
+        this.pubId = null;
+        this.area = null;
+        this.pathElements.clear();
     }
 
 }

Modified: lenya/trunk/src/modules/sitetree/resources/javascript/lenyatree.js
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sitetree/resources/javascript/lenyatree.js?rev=736668&r1=736667&r2=736668&view=diff
==============================================================================
--- lenya/trunk/src/modules/sitetree/resources/javascript/lenyatree.js (original)
+++ lenya/trunk/src/modules/sitetree/resources/javascript/lenyatree.js Thu Jan 22 07:16:06 2009
@@ -19,7 +19,6 @@
 /*
   The following variables must be set:
   WEBAPP_BASE_PATH - path to the web application root, including the trailing slash
-  AREA_BASE_PATH - path to the area root, without the trailing slash
   PUBLICATION_ID
   PIPELINE_PATH
   IMAGE_PATH
@@ -85,7 +84,7 @@
 
 LenyaNode.prototype.getLoadSubTreeURL = function() {
     var path = this.getPath();
-    return encodeURI(AREA_BASE_PATH + PIPELINE_PATH + '?path='+path+'&lenya.module=sitetree');
+    return encodeURI(WEBAPP_BASE_PATH + PIPELINE_PATH + '?path='+path+'&lenya.module=sitetree');
 }
 
 
@@ -195,7 +194,7 @@
 };
 
 LenyaTree.prototype.getLoadInitialTreeURL = function(path) {
-    return encodeURI(AREA_BASE_PATH + PIPELINE_PATH + '?path='+path+'&lenya.module=sitetree');
+    return encodeURI(WEBAPP_BASE_PATH + PIPELINE_PATH + '?path='+path+'&lenya.module=sitetree');
 }
 
 LenyaTree.prototype.initialTreeLoaded = function(xml) {
@@ -246,7 +245,7 @@
         else {
             var href;
             if (steps.length < 4) {
-                href = AREA_BASE_PATH + "/folder.gif?lenya.module=sitetree";
+                href = WEBAPP_BASE_PATH + "modules/sitetree/folder.gif";
             }
             else {
                 href = item.icon;

Modified: lenya/trunk/src/modules/sitetree/resources/javascript/navtree.js
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sitetree/resources/javascript/navtree.js?rev=736668&r1=736667&r2=736668&view=diff
==============================================================================
--- lenya/trunk/src/modules/sitetree/resources/javascript/navtree.js (original)
+++ lenya/trunk/src/modules/sitetree/resources/javascript/navtree.js Thu Jan 22 07:16:06 2009
@@ -67,7 +67,13 @@
 NavNode.prototype.getLoadSubTreeURL = function() {
     area = this.area;
     var path = this.getBasePath();
-    return encodeURI(AREA_BASE_PATH + PIPELINE_PATH + '?area='+area+'&path='+path+'&language='+CHOSEN_LANGUAGE+'&areas='+ALL_AREAS+'&lenya.module=sitetree');
+    return encodeURI(WEBAPP_BASE_PATH + PIPELINE_PATH
+        + '?pub=' + PUBLICATION_ID
+        + '&area=' + area
+        + '&path=' + path
+        + '&language=' + CHOSEN_LANGUAGE
+        + '&defaultLanguage=' + DEFAULT_LANGUAGE
+        + '&areas=' + ALL_AREAS);
 }
 
 NavNode.prototype.getStyle = function() {
@@ -155,7 +161,14 @@
 };
 
 NavTree.prototype.loadInitialTree = function(area, path) {
-    var url = encodeURI(AREA_BASE_PATH + PIPELINE_PATH + '?area='+area+'&path='+path+'&language='+CHOSEN_LANGUAGE+'&initial=true&areas='+ALL_AREAS+'&lenya.module=sitetree');
+    var url = encodeURI(WEBAPP_BASE_PATH + PIPELINE_PATH + '?'
+        + 'pub=' + PUBLICATION_ID
+        + '&area=' + area
+        + '&path=' + path
+        + '&defaultLanguage=' + DEFAULT_LANGUAGE
+        + '&language=' + CHOSEN_LANGUAGE
+        + '&initial=true'
+        + '&areas=' + ALL_AREAS);
     
     callback = function(fragment, param) {
         var tree = param[0];

Modified: lenya/trunk/src/modules/sitetree/sitemap.xmap
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules/sitetree/sitemap.xmap?rev=736668&r1=736667&r2=736668&view=diff
==============================================================================
--- lenya/trunk/src/modules/sitetree/sitemap.xmap (original)
+++ lenya/trunk/src/modules/sitetree/sitemap.xmap Thu Jan 22 07:16:06 2009
@@ -128,35 +128,39 @@
         <map:serialize type="xml"/>
       </map:match>
       
-      <!-- {publication-id}/{area}/info-sitetree -->
-      <map:match pattern="*/*/sitetree-fragment.xml">
+      <map:match pattern="sitetree-fragment.xml">
         <map:generate type="sitetree-fragment">
-          <map:parameter name="areas" value="{request-param:areas}"/>
+          <map:parameter name="pub" value="{request-param:pub}"/>
           <map:parameter name="area" value="{request-param:area}"/>
+          <map:parameter name="areas" value="{request-param:areas}"/>
           <map:parameter name="path" value="{request-param:path}"/>
           <map:parameter name="initial" value="{request-param:initial}"/>
           <map:parameter name="mimetype" value="{request-param:mimetype}"/>
         </map:generate>
         <!-- <map:call resource="i18n"/> -->
-        <map:transform type="access-control-sitetree">
-          <map:parameter name="publication-id" value="{1}"/>
-          <map:parameter name="area" value="{2}"/>
-        </map:transform>
+        <map:transform type="access-control-sitetree"/>
         <map:act type="set-header">
           <map:parameter name="Cache-Control" value="pre-check=0" />
           <map:parameter name="Expires" value="-1" />
         </map:act>
         <map:transform src="fallback://lenya/modules/sitetree/xslt/navigation/sitetree2nav.xsl" label="navtree">
           <map:parameter name="chosenlanguage" value="{request-param:language}"/>
-          <map:parameter name="defaultlanguage" value="{page-envelope:default-language}"/>
+          <map:parameter name="defaultlanguage" value="{request-param:defaultLanguage}"/>
           <map:parameter name="extension" value="html"/>
         </map:transform>
         <map:transform type="i18n">
           <map:parameter name="locale" value="{request:locale}"/>
         </map:transform>
-        <map:transform type="uuid2url-sitetree"/>
-        <map:transform type="icon-sitetree"/>
-        <map:transform type="proxy-sitetree"/>
+        <map:transform type="uuid2url-sitetree">
+          <map:parameter name="url" value="/{request-param:pub}/{request-param:area}/"/>
+        </map:transform>
+        <map:transform type="icon-sitetree">
+          <map:parameter name="url" value="/{request-param:pub}/{request-param:area}/"/>
+        </map:transform>
+        <map:transform type="proxy-sitetree">
+          <map:parameter name="pub" value="{request-param:pub}"/>
+          <map:parameter name="area" value="{request-param:area}"/>
+        </map:transform>
         <map:serialize type="xml"/>
       </map:match>
     </map:pipeline>
@@ -172,16 +176,16 @@
     <!-- Resource type icons -->
     <map:pipeline>
       
-      <map:match pattern="*/*/folder.gif">
+      <map:match pattern="folder.gif">
         <map:read src="fallback://lenya/modules/sitetree/resources/icons/folder.gif"/>
       </map:match>
 
-      <map:match pattern="*/*/default.gif">
+      <map:match pattern="default.gif">
         <map:read src="fallback://lenya/modules/sitetree/resources/icons/default.gif"/>
       </map:match> 
       
-      <map:match pattern="*/*/*.gif">
-        <map:read src="{resource-type:{3}:format-icon}" mime-type="image/gif"/>
+      <map:match pattern="*.gif">
+        <map:read src="{resource-type:{1}:format-icon}" mime-type="image/gif"/>
       </map:match>
     </map:pipeline>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.