[opencms-dev] some bug fixes and enhancements for OpenCms 5.0.1

Vincent Hanniet vhanniet at free.fr
Wed Jul 7 16:52:01 CEST 2004


Very good idea. Thank you Sven from Getit !
Vincent

Sven Bonorden wrote:

> Hi all,
> 
> during our work with OpenCms 5.0.1 we had to change many classes of the 
> OpenCms core itself.
> Our main work is commercial and very customer-specific, but the core 
> changes are of course Open Source.
> I collected the bug fixes and enhancements so anyone having similar 
> problems can use our solutions.
> 
> Maybe some of our modifications could also be added to version 6 but I 
> did not check if they work in the current CVS head as we only used 5.0.1.
> That's why I did not add the complete java files or patch files so the 
> core developers can decide what may be necessary.
> 
> Bug fixes (details see attached file, some of them are already in Bugzilla)
> - When restoring an old version of a resource, the properties of this 
> version are not restored (#361)
> - Log channels in property file have wrong names and so they are never 
> used.
> - When a folder is copied and the destination folder already exists, the 
> copying fails (#362)
> - You cannot add new resource types if their classes are in a module
> - Moving or renaming a folder resource does not move the /system/bodies 
> folder (#363)
> - Cms always sents Mails in charset ISO8859-1
> - Link substitution ignores urls in <input src="..."> and <form 
> action="...">
> - The source editor cannot display special characters from Eastern Europe
> - Some German spelling errors, mainly to fix different spellings of 
> "Ressource"
> - CmsRequestContext.getSession fails with NullPointerException if no 
> request is available
> - Scheduler does not start jobs if the minute is 0 (#74)
> - when creating a resource, the property values (i.e. title) are not 
> encoded correctly on some systems
> - It is impossible to disable the scheduler when creating a new CmsObject
> - In CmsResourceBroker some methods change the file-state after saving 
> the file. That does not make sense.
> - If copying a resource, the owner and group are also copied from the 
> source.
> - CmsResourceBroker.readAllFileHeadersForHist throws a CmsException if 
> the resource has been deleted (#348)
> - Two different backup versions of a resource are considered equal
> - Trying to send a mail from a scheduled job fails with 
> NullPointerException (#364)
> - Access checks for read and visible return a wrong result if the user 
> has these privileges via his group (#365)
> 
> Enhancements (details see attached file)
> - Change the group for a resource recursively from CmsShell
> - Methods to access a project with a specific name from CmsShell
> - Methods to read properties from a backup version for a resource
> - CmsSetupUtils cannot read Property values containing a comma
> - Functionality for users to be logged in without a password
> - Workplace Popup for folder tree always starts with root folder
> - You cannot get a specific project by its name
> - write a property if the property definition does not exist
> - find a folder with a specific name searching only through a part of VFS
> - find all resources in a folder that have been published after a 
> specific date
> - get the resource type of a deleted resource
> - folder tree popup to show not only the name, but also the title
> 
> Kind regards,
> Sven
> 
> 
> ------------------------------------------------------------------------
> 
> Bugfixes for OpenCms 5.0.1:
> -------------------------------
> 
> This file lists bugfixes made by GETIT GmbH for productional use of OpenCms 5.0.1.
> 
> ---------------------------------------------------------------------------------------------------
> 
> Bug 361:
> When restoring an old version of a resource, the properties of this version are not restored.
> 
> com.opencms.file.genericSql.CmsDbAccess:
> - new method:
>     /**
>      * Returns a list of all history properties of a file or folder.<p>
>      *
>      * @param resourceId the id of the resource
>      * @param resource the resource to read the properties from
>      * @param resourceType the type of the resource
>      *
>      * @return a Map of Strings representing the properties of the resource
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public HashMap readPropertiesForHist(CmsResource resource, int resourceType)
>         throws CmsException {
> 
>         HashMap returnValue = new HashMap();
>         ResultSet result = null;
>         PreparedStatement statement = null;
>         Connection con = null;
>         String usedPool;
>         int resourceId = resource.getResourceId();
>         //int onlineProject = getOnlineProject(projectId).getId();
>         usedPool = m_poolNameBackup;
>         try {
>            con = DriverManager.getConnection(usedPool);
>             // create project
>             statement = con.prepareStatement(m_cq.get("C_PROPERTIES_READALL_BACKUP"));
>             statement.setInt(1, resourceId);
>             statement.setInt(2, resourceType);
>             result = statement.executeQuery();
>             while(result.next()) {
>                  returnValue.put(result.getString(m_cq.get("C_PROPERTYDEF_NAME")),
>                                  result.getString(m_cq.get("C_PROPERTY_VALUE")));
>             }
>         } catch( SQLException exc ) {
>             throw new CmsException("[" + this.getClass().getName() + "] " + exc.getMessage(),
>                 CmsException.C_SQL_ERROR, exc);
>         } finally {
>             // close all db-resources
>             if(result != null) {
>                 try {
>                     result.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(statement != null) {
>                 try {
>                     statement.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(con != null) {
>                 try {
>                     con.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>         }
>         return(returnValue);
>     }
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - new constant:
>     protected static final String C_CACHE_ALL_BACKUP_PROPERTIES = "__CACHE_ALL_BACKUP_PROPERTIES__";
> 
> - new method:
>     /**
>      * Looks up all properties for a resource with optional direcory upward cascading.<p>
>      * 
>      * 
>      * @param currentUser the current user
>      * @param currentProject the current project of the user
>      * @param resource the resource to look up the property for
>      * @param siteRoot the current site root
>      * @param search if <code>true</code>, the properties will also be looked up on all parent folders
>      *   and the results will be merged, if <code>false</code> not (ie. normal property lookup)
>      * @return Map of Strings representing all properties of the resource
>      * @throws CmsException in case there where problems reading the properties
>      */
>     public Map readPropertiesForHist(CmsUser currentUser, CmsProject currentProject, String resource, String siteRoot, boolean search, int version_id) 
>     throws CmsException {
>         // read the resource from history
>         CmsResource res = readFileForHist (currentUser, currentProject, version_id,resource);
>         
>         search = search && (siteRoot != null);
>         // check if we have the result already cached
>         HashMap value = null;
>         
>         String cacheKey = getCacheKey(C_CACHE_ALL_BACKUP_PROPERTIES + search+version_id, null, new CmsProject(currentProject.getId(), -1), res.getResourceName());
>         value = (HashMap)m_propertyCache.get(cacheKey);
>         
>         if (value == null) {
>             // result not cached, let's look it up in the DB
>             if (search) {
>                 boolean cont;
>                 siteRoot += "/";
>                 value = new HashMap();
>                 HashMap parentValue;
>                 do {
>                     parentValue = (HashMap)readProperties(currentUser, currentProject, resource, siteRoot, false);
>                     parentValue.putAll(value);
>                     value.clear();
>                     value.putAll(parentValue);
>                     resource = CmsResource.getParent(resource);
>                     cont = (! siteRoot.equals(resource));
>                 } while (cont);
>             } else {
>                 value = m_dbAccess.readPropertiesForHist(res, res.getType());
>             }  
>             // store the result in the cache
>             m_propertyCache.put(cacheKey, value);
>         }
>         return (Map)value.clone();
>     }    
> 
> - change method restoreResource:
> old version:
>             writeFile(currentUser, currentProject, newFile);
> 
> new version:
>             writeFile(currentUser, currentProject, newFile);
>             deleteAllProperties(currentUser,currentProject,newFile.getResourceName());
>             Map oldProperties = readPropertiesForHist(currentUser,currentProject,newFile.getResourceName(),null,false,versionId);
>             writeProperties(currentUser,currentProject,newFile.getResourceName(),oldProperties);
> 
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Looks up all properties from a backup resource with optional directory upward cascading.<p>
>      * 
>      * <b>Security:</b>
>      * Only a user is granted who has the right to read the resource.
>      * 
>      * @param currentUser the current user
>      * @param currentProject the current project of the user
>      * @param resource the resource to look up the property for
>      * @param siteroot the site root where to stop the cascading
>      * @param search if <code>true</code>, the properties will also be looked up on all parent folders
>      *   and the results will be merged, if <code>false</code> not (ie. normal property lookup)
>      * @param versionId the version id containing the defined properties
>      * @return Map of Strings representing all properties of the resource
>      * @throws CmsException in case there where problems reading the properties
>      */
> 	public Map readPropertiesForHist(CmsUser currentUser, CmsProject currentProject, String resource, String siteRoot, boolean search, int versionId) throws CmsException;    
> 
> com.opencms.file.CmsObject:
> - new method:
>     /**
>      * Looks up all properties for a resource.<p>
>      * 
>      * @param resource the resource to look up the property for
>      * @param versionId the requeste version of the resource
>      * @return Map of Strings representing all properties of the resource
>      * @throws CmsException in case there where problems reading the properties
>      */  
>     public Map readProperties(String resource,int versionId) throws CmsException {
>     	return m_rb.readPropertiesForHist(m_context.currentUser(), m_context.currentProject(), m_context.getSiteRoot(resource), m_context.getSiteRoot(), false,versionId);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Log channels in property file have wrong names and so they are never used.
> 
> opencms.properties:
> old version:
>     log.channel.module_debug=false
>     log.channel.module_info=true
>     log.channel.module_critical=true
> 
> new version:
>     log.channel.modules_debug=false
>     log.channel.modules_info=true
>     log.channel.modules_critical=true
> 
> ---------------------------------------------------------------------------------------------------
> 
> Bug 362
> When a folder is copied and the destination folder already exists, the copying fails.
> We added a check before creating the destination.
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - change method copyFile:
> old version:
>                 m_dbAccess.createFolder(currentUser,currentProject, onlineProject(currentUser, currentProject), folder,cmsFolder.getResourceId(),destination);
> new version:
>                 // Check if folder already exists before trying to create it
>                 CmsFolder oldFolder=null;
>                 try {
>                  oldFolder = readFolder(currentUser,currentProject,destination);
>                 } catch (CmsException e) {
>                 }
>                 if (oldFolder==null) m_dbAccess.createFolder(currentUser,currentProject, onlineProject(currentUser, currentProject), folder,cmsFolder.getResourceId(),destination);
> 
> ---------------------------------------------------------------------------------------------------
> 
> You cannot add new resource types if their classes are in a module.
> If you add resource types to registry.xml and the module is not installed yet, 
> OpenCms stops with a ClassNotFoundException
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - change method getAllResourceTypes
> old version:
>                     }catch(Exception e){
>                         e.printStackTrace();
>                         throw new CmsException("[" + this.getClass().getName() + "] Error while getting ResourceType: " 
>                             + (String)resTypeNames.elementAt(i) + " from registry ", CmsException.C_UNKNOWN_EXCEPTION );
>                     }
> 
> new version:
>                     }catch(Exception e){
>                         e.printStackTrace();
>                         if (e instanceof ClassNotFoundException) {
>                             // ignore this exception. 
>                             // maybe a module has added a new resource type to registry.xml
>                             // but the classes are not yet installed 
>                         } else {
>                             throw new CmsException("[" + this.getClass().getName() + "] Error while getting ResourceType: " 
>                                 + (String)resTypeNames.elementAt(i) + " from registry ", CmsException.C_UNKNOWN_EXCEPTION );
>                         }
>                     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Bug 363:
> Moving or renaming a folder resource does not move the /system/bodies folder so bodies are lost for ever if you rename or move a folder.
> We fixed the bug by removing redundant code.
> 
> com.opencms.file.CmsResourceTypeFolder.java:
> - change Method moveResource:
> old Version:
>     public void moveResource(CmsObject cms, String source, String destination) throws CmsException{
>         // it is a folder so we need the end /
>         destination = destination +"/";
>        // we have to copy the folder and all resources in the folder
>         Vector allSubFolders = new Vector();
>         Vector allSubFiles   = new Vector();
>         getAllResources(cms, source, allSubFiles, allSubFolders);
>         if(!cms.accessWrite(source)){
>             throw new CmsException(source, CmsException.C_NO_ACCESS);
>         }
>         // first copy the folder
>         cms.doCopyFolder(source, destination);
>         // now copy the subfolders
>         for (int i=0; i<allSubFolders.size(); i++){
>             CmsFolder curFolder = (CmsFolder) allSubFolders.elementAt(i);
>             if(curFolder.getState() != C_STATE_DELETED){
>                 String curDestination = destination + curFolder.getAbsolutePath().substring(source.length());
>                 cms.doCopyFolder(curFolder.getAbsolutePath(), curDestination );
>             }
>         }
>         // now move the files
>         for (int i=0; i<allSubFiles.size(); i++){
>             CmsFile curFile = (CmsFile)allSubFiles.elementAt(i);
>             if(curFile.getState() != C_STATE_DELETED){
>                 String curDest = destination + curFile.getAbsolutePath().substring(source.length());
>                 cms.moveResource(curFile.getAbsolutePath(), curDest);
>             }
>         }
>         // finaly remove the original folders
>         deleteResource(cms, source);
>     }
> 
> new version:
>     public void moveResource(CmsObject cms, String source, String destination) throws CmsException{
>        
>         copyResource(cms, source, destination, true);
>         // finally remove the original folders
>         deleteResource(cms, source);
>     }
> 
> - change Method renameResource:
> old version:
>     public void renameResource(CmsObject cms, String oldname, String newname) throws CmsException{
>         // first of all check the new name
>         validResourcename(newname.replace('/','\n'));
>        // we have to copy the folder and all resources in the folder
>         Vector allSubFolders = new Vector();
>         Vector allSubFiles   = new Vector();
>         getAllResources(cms, oldname, allSubFiles, allSubFolders);
>         String parent = ((CmsResource)cms.readFileHeader(oldname)).getParent();
>         if(!cms.accessWrite(oldname)){
>             throw new CmsException(oldname, CmsException.C_NO_ACCESS);
>         }
>         if(!newname.endsWith("/")){
>             newname = newname+"/";
>         }
>         // first copy the folder
>         cms.doCopyFolder(oldname, parent + newname);
>         // now copy the subfolders
>         for (int i=0; i<allSubFolders.size(); i++){
>             CmsFolder curFolder = (CmsFolder) allSubFolders.elementAt(i);
>             if(curFolder.getState() != C_STATE_DELETED){
>                 String curDestination = parent + newname
>                                         + curFolder.getAbsolutePath().substring(oldname.length());
>                 cms.doCopyFolder(curFolder.getAbsolutePath(), curDestination );
>             }
>         }
>         // now move the files
>         for (int i=0; i<allSubFiles.size(); i++){
>             CmsFile curFile = (CmsFile)allSubFiles.elementAt(i);
>             if(curFile.getState() != C_STATE_DELETED){
>                 String curDest = parent + newname
>                                 + curFile.getAbsolutePath().substring(oldname.length());
>                 cms.moveResource(curFile.getAbsolutePath(), curDest);
>             }
>         }
>         // finaly remove the original folders
>         deleteResource(cms, oldname);
> 
>     }
> 
> new version:
>     public void renameResource(CmsObject cms, String oldname, String newname) throws CmsException{
>         // first of all check the new name
>         validResourcename(newname.replace('/','\n'));
> 
>         String parent = ((CmsResource)cms.readFileHeader(oldname)).getParent();
>         if(!cms.accessWrite(oldname)){
>             throw new CmsException(oldname, CmsException.C_NO_ACCESS);
>         }
> 
>         moveResource(cms, oldname, parent + newname);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Cms always sents Mails in charset ISO8859-1 so special chars not contained in this charset will get messed up.
> We changed the class to work with UTF-8 which is our default charset - would be better to choose charset dynamically
> from setup...
> See also Bug #83. We did not check the solution suggested there.
> 
> com.opencms.defaults.CmsMail
> - change method buildMessage
> old version:
>         // Default encoding for new mail message
>         String mail_encoding = "ISO-8859-1";
>         
>         ...
>         
>         msg.setSentDate(new Date());
>         return msg;
>         
> version for UTF-8:
>         // Default encoding for new mail message
>         String mail_encoding = "UTF-8"; 
>         
>         ...
>         
>         msg.setSentDate(new Date());
>         // following statement added because otherwise mail is always sent
>         // with Content-Type "text/plain" in the header
>         // and charset defaults to ISO-8859-1                 
>         msg.setHeader("Content-Type", c_TYPE + "; charset=UTF-8");
>         
>         return msg;
> 
> ---------------------------------------------------------------------------------------------------
> 
> Link substitution ignores urls in <input src="..."> and <form action="...">
> 
> com.opencms.util.LinkSubstitution.java:
> - change static String m_converterConfiguration
> old version:
>             "   <replacetags usedefaults=\"true\">"+
>             "       <tag name=\"img\" attrib=\"src\" replacestarttag=\"]]><LINK><![CDATA[$parameter$]]></LINK><![CDATA[\" parameter=\"src\" replaceparamattr=\"true\"/>"+
>             "       <tag name=\"a\" attrib=\"href\" replacestarttag=\"]]><LINK><![CDATA[$parameter$]]></LINK><![CDATA[\" replaceendtag=\"</a>\" parameter=\"href\" replaceparamattr=\"true\"/>"+
>             "   </replacetags>"+
> 
> new version:
>             "   <replacetags usedefaults=\"true\">"+
>             "       <tag name=\"img\" attrib=\"src\" replacestarttag=\"]]><LINK><![CDATA[$parameter$]]></LINK><![CDATA[\" parameter=\"src\" replaceparamattr=\"true\"/>"+
>             "       <tag name=\"input\" attrib=\"src\" replacestarttag=\"]]><LINK><![CDATA[$parameter$]]></LINK><![CDATA[\" parameter=\"src\" replaceparamattr=\"true\"/>"+
>             "       <tag name=\"form\" attrib=\"action\" replacestarttag=\"]]><LINK><![CDATA[$parameter$]]></LINK><![CDATA[\" parameter=\"action\" replaceparamattr=\"true\"/>"+  
>             "       <tag name=\"a\" attrib=\"href\" replacestarttag=\"]]><LINK><![CDATA[$parameter$]]></LINK><![CDATA[\" replaceendtag=\"</a>\" parameter=\"href\" replaceparamattr=\"true\"/>"+
>             "   </replacetags>"+
> 
> ---------------------------------------------------------------------------------------------------
> 
> The source editor cannot display special characters from Eastern Europe. We changed the default charset from FixedSys to Courier New 
> which contains many more characters.
> 
> /etc/ocsetup/vfs/system/workplace/templates/edit_text_main:
> old version:
> 	<!-- write the text area -->
> 	<script language="JavaScript">
> 	<!--      
> 		str = '<textarea wrap="off" name="edit1" onfocus="setTextDelayed();" style="width:100%; height:100%; font-family:Fixedsys, monospace"></textarea>';
> 		document.write(str);
> 	//-->
> 	</script>
> 
>     new version:
> 	<!-- write the text area -->
> 	<script language="JavaScript">
> 	<!--      
> 		str = '<textarea wrap="off" name="edit1" onfocus="setTextDelayed();" style="width:100%; height:100%; font-family:Courier New, monospace"></textarea>';
> 		document.write(str);
> 	//-->
> 
> ---------------------------------------------------------------------------------------------------
> 
> Some German spelling errors, mainly to fix different spellings of "Ressource".
> 
> com.opencms.workplace.workplace_de.properties:
> old version:
> report.publish_resource_begin=Gebe Resource(n) frei ...
> report.publish_resource_end=... die Resource(n) wurde(n) freigegeben
> error.message.accessdenied=Leider konnte auf die Resource nicht zugegriffen werden.
> module.context.admin=Administieren
> flexcache.admin.label3=Zeige gecachte Resources mit Schlüsseln an
> flexcache.admin.label4=Zeige gecachte Resources mit Schlüsseln und Variationen an
> flexcache.admin.cached_resources=Momentan gecachte Resourcen
> flexcache.admin.cached_keys_variants=Gecachte Resourcen mit Schlüsseln und Variationen:
> flexcache.admin.cached_keys=Gecachte Resourcen mit Schlüsseln:
> flexcache.admin.online=Online Resourcen:
> flexcache.admin.offline=Offline Resourcen:
> flexcache.admin.err_online=Keine gecachten Online Resourcen!
> flexcache.admin.err_offline=Keine gecachten Offline Resourcen!
> flexcache.admin.resource=Resource
> 
> new version:
> report.publish_resource_begin=Gebe Ressource(n) frei ...
> report.publish_resource_end=... die Ressource(n) wurde(n) freigegeben
> error.message.accessdenied=Leider konnte auf die Ressource nicht zugegriffen werden.
> module.context.admin=Administrieren
> flexcache.admin.label3=Zeige gecachte Ressourcen mit Schlüsseln an
> flexcache.admin.label4=Zeige gecachte Ressourcen mit Schlüsseln und Variationen an
> flexcache.admin.cached_resources=Momentan gecachte Ressourcen
> flexcache.admin.cached_keys_variants=Gecachte Ressourcen mit Schlüsseln und Variationen:
> flexcache.admin.cached_keys=Gecachte Ressourcen mit Schlüsseln:
> flexcache.admin.online=Online Ressourcen:
> flexcache.admin.offline=Offline Ressourcen:
> flexcache.admin.err_online=Keine gecachten Online Ressourcen!
> flexcache.admin.err_offline=Keine gecachten Offline Ressourcen!
> flexcache.admin.resource=Ressource
> 
> ---------------------------------------------------------------------------------------------------
> 
> CmsRequestContext.getSession fails with NullPointerException if no request is available 
> which is possible if called in scheduled jobs.
> 
> com.opencms.file.CmsRequestContext:
> - change method getSession
> old version:
>     public I_CmsSession getSession(boolean value) {
>         HttpSession session =
>             ((HttpServletRequest) m_req.getOriginalRequest()).getSession(value);
>         if (session != null) {
>             return (I_CmsSession) new CmsSession(session);
>         } else {
>             return null;
>         }
>     }
> 
> new version:
>     public I_CmsSession getSession(boolean value) {
>         // added checks for null.
>         if (m_req == null || m_req.getOriginalRequest() == null) {
>             return null;
>         }
>         
>         HttpSession session =
>             ((HttpServletRequest) m_req.getOriginalRequest()).getSession(value);
>         if (session != null) {
>             return (I_CmsSession) new CmsSession(session);
>         } else {
>             return null;
>         }
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Fix for Bugzilla #74: Scheduler does not start jobs if the minute is 0.
> 
> com.opencms.core.CmsCronEntry.java:
> - change Method check:
> old version:
>         if(m_minute != C_ASTERIX) // check the minute
>     		if(!isBetween(lastTime.get(Calendar.MINUTE), m_minute, now.get(Calendar.MINUTE)))
> 	    		return false;
> 
> new version:
>         if(m_minute != C_ASTERIX) { // check the minute
>             // changed to correct condition if lastTime was in last hour 
>             // (minute 59 < minute 0)
>             int lastTimeMinute = lastTime.get(Calendar.MINUTE);
>             int nowMinute = now.get(Calendar.MINUTE);
>             while (lastTimeMinute > nowMinute) { 
>                 lastTimeMinute -= 60;
>             }
>    	    if(!isBetween(lastTimeMinute, m_minute, nowMinute))
> 	    		return false;
>         }
> 
> ---------------------------------------------------------------------------------------------------
> 
> On some systems, when creating a resource, the entered strings for property values (i.e. title) are not
> encoded correctly. German umlauts are replaced by question marks.
> We had this problem on a SUSE Linux using an IBM JDK and Java system property file.encoding=UTF-8. 
> This could be solved by always explicitly specifying an encoding when converting Strings to bytes and back.
> 
> com.opencms.utils.Encoder:
> - change method redecodeUriComponent:
> old version:
>     public static String redecodeUriComponent(String input) {
>        if (input == null) return input;
>        return new String(changeEncoding(input.getBytes(), C_URI_ENCODING, A_OpenCms.getDefaultEncoding())); 
>     }
> 
> new version:
>     public static String redecodeUriComponent(String input) {
>        if (input == null) return input;
>        // added encoding for getBytes and new String because otherwise 
>        // platform default encoding is used which may destroy some characters 
>        try {
>            return new String(changeEncoding(input.getBytes(C_URI_ENCODING), C_URI_ENCODING, A_OpenCms.getDefaultEncoding()), 
>                              A_OpenCms.getDefaultEncoding()); 
>        } catch (UnsupportedEncodingException e) {
>            return new String(changeEncoding(input.getBytes(), C_URI_ENCODING, A_OpenCms.getDefaultEncoding())); 
>        }
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> It is impossible to disable the scheduler when creating a new CmsObject because this property is always read from 
> system properties, ignoring the specified properties (this behaviour is different from all other properties)
> 
> com.opencms.core.OpenCms:
> - change constructor OpenCms
> old version:
>             // if the System property opencms.disableScheduler is set to true, don't start scheduling
>             if(!new Boolean(System.getProperty("opencms.disableScheduler")).booleanValue()) {
>                 // now initialise the OpenCms scheduler to launch cronjobs
>                 m_table = new CmsCronTable(m_resourceBroker.readCronTable(null, null));
>                 m_scheduler = new CmsCronScheduler(this, m_table);
>                 if(C_LOGGING && isLogging(C_OPENCMS_INIT)) log(C_OPENCMS_INIT, ". OpenCms scheduler    : enabled");
>             } else {
>                 if(C_LOGGING && isLogging(C_OPENCMS_INIT)) log(C_OPENCMS_INIT, ". OpenCms scheduler    : disabled");
>             }
> new version:
>             // if the property opencms.disableScheduler is set to true, don't start scheduling
>             if(!conf.getBoolean("opencms.disableScheduler", false)) {
>                 // now initialise the OpenCms scheduler to launch cronjobs
>                 m_table = new CmsCronTable(m_resourceBroker.readCronTable(null, null));
>                 m_scheduler = new CmsCronScheduler(this, m_table);
>                 if(C_LOGGING && isLogging(C_OPENCMS_INIT)) log(C_OPENCMS_INIT, ". OpenCms scheduler    : enabled");
>             } else {
>                 if(C_LOGGING && isLogging(C_OPENCMS_INIT)) log(C_OPENCMS_INIT, ". OpenCms scheduler    : disabled");
>             }
> 
> ---------------------------------------------------------------------------------------------------
> 
> In CmsResourceBroker some methods change the file-state after saving the file. That does not make sense.
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - change method writeProperty:
> old version:
>         if(res.isFile()){
>             m_dbAccess.writeFileHeader(currentProject, (CmsFile) res, true, currentUser.getId());
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>         } else {
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>             m_dbAccess.writeFolder(currentProject, readFolder(currentUser,currentProject, resource), true, currentUser.getId());
>         }
> new version:
>         if(res.isFile()){
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>             m_dbAccess.writeFileHeader(currentProject, (CmsFile) res, true, currentUser.getId());
>         } else {
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>             m_dbAccess.writeFolder(currentProject, readFolder(currentUser,currentProject, resource), true, currentUser.getId());
>         }
> 
> 
> The same holds for methods chgrp, chmod, chown, chtype, deleteProperty, writeFile, writeFileHeader.
> 
> 
> 
> ---------------------------------------------------------------------------------------------------
> 
> If copying a resource, the owner and group are also copied from the source. So if you copy a resource not owned by yourself,
> you may not be allowed to change it afterwards. As you are not the owner, you cannot change the owner to yourself after copying.
> When copying files in a real file system, the owner is changed so we implemented the same behaviour for VFS.
> As moving and renaming is implemented by copy & delete, the same holds for move and rename.
> 
> This change could only be realized at a level below the access checks, because otherwise we would not have the privilege to change the owner.
> Therefore, we had to change some signatures.
> 
> com.opencms.file.genericSql.CmsDbAccess
> - add return value to method copyFile
> old version:
>     /**
>      * Copies the file.
>      *
>      * @param project The project in which the resource will be used.
>      * @param onlineProject The online project of the OpenCms.
>      * @param userId The id of the user who wants to copy the file.
>      * @param source The complete path of the sourcefile.
>      * @param parentId The parentId of the resource.
>      * @param destination The complete path of the destinationfile.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful.
>      */
>      public void copyFile(CmsProject project,
>                           CmsProject onlineProject,
>                           int userId,
>                           String source,
>                           int parentId,
>                           String destination)
>          throws CmsException {
>          CmsFile file;
> 
>          // read sourcefile
>          file=readFile(project.getId(),onlineProject.getId(),source);
>          // create destination file
>          createFile(project,onlineProject,file,userId,parentId,destination);
>      }
> 
> new version:
>     /**
>      * Copies the file.
>      *
>      * @param project The project in which the resource will be used.
>      * @param onlineProject The online project of the OpenCms.
>      * @param userId The id of the user who wants to copy the file.
>      * @param source The complete path of the sourcefile.
>      * @param parentId The parentId of the resource.
>      * @param destination The complete path of the destinationfile.
>      * 
>      * @return the created destination file
>      * @throws CmsException Throws CmsException if operation was not succesful.
>      */
>      public CmsFile copyFile(CmsProject project,
>                           CmsProject onlineProject,
>                           int userId,
>                           String source,
>                           int parentId,
>                           String destination)
>          throws CmsException {
>          CmsFile file;
> 
>          // read sourcefile
>          file=readFile(project.getId(),onlineProject.getId(),source);
>          // create destination file
>          return createFile(project,onlineProject,file,userId,parentId,destination);
>      }
> 
> 
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - change method copyFile:
> old version:
>     /**
>      * Copies a file in the Cms. <br>
>      *
>      * <B>Security:</B>
>      * Access is granted, if:
>      * <ul>
>      * <li>the user has access to the project</li>
>      * <li>the user can read the sourceresource</li>
>      * <li>the user can create the destinationresource</li>
>      * <li>the destinationresource doesn't exist</li>
>      * </ul>
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param source The complete path of the sourcefile.
>      * @param destination The complete path to the destination.
>      *
>      * @throws CmsException  Throws CmsException if operation was not succesful.
>      */
>     public void copyFile(CmsUser currentUser, CmsProject currentProject,
>                          String source, String destination)
>         throws CmsException {
> 
>         // the name of the new file.
>         String filename;
>         // the name of the folder.
>         String foldername;
> 
>         // checks, if the destinateion is valid, if not it throws a exception
>         validFilename(destination.replace('/', 'a'));
> 
>         // read the source-file, to check readaccess
>         CmsResource file = readFileHeader(currentUser, currentProject, source);
> 
>         // split the destination into file and foldername
>         if (destination.endsWith("/")) {
>             filename = file.getName();
>             foldername = destination;
>         }else{
>             foldername = destination.substring(0, destination.lastIndexOf("/")+1);
>             filename = destination.substring(destination.lastIndexOf("/")+1,
>                                              destination.length());
>         }
> 
>         CmsFolder cmsFolder = readFolder(currentUser,currentProject, foldername);
>         if( accessCreate(currentUser, currentProject, (CmsResource)cmsFolder) ) {
>             if(( accessOther(file, C_ACCESS_PUBLIC_WRITE) ||
>                 accessOwner(currentUser, currentProject, file, C_ACCESS_OWNER_WRITE) ||
>                 accessGroup(currentUser, currentProject, file, C_ACCESS_GROUP_WRITE) )){
>                 // write-acces  was granted - copy the file and the metainfos
>                 m_dbAccess.copyFile(currentProject, onlineProject(currentUser, currentProject),
>                               currentUser.getId(),source,cmsFolder.getResourceId(), foldername + filename);
> 
>                 this.clearResourceCache(foldername + filename, currentProject, currentUser);
>                 // copy the metainfos
>                 lockResource(currentUser, currentProject, destination, true);
>                 writeProperties(currentUser,currentProject, destination,
>                             readProperties(currentUser, currentProject, file.getResourceName(), null, false));
>                 m_accessCache.clear();
>                 // inform about the file-system-change
>                 fileSystemChanged(file.isFolder());
>             } else {
>                 throw new CmsException("[" + this.getClass().getName() + "] " + source,
>                     CmsException.C_NO_ACCESS);
>             }
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + destination,
>                 CmsException.C_NO_ACCESS);
>         }
>     }
> 
> new version:
>     /**
>      * Copies a file in the Cms. <br>
>      * The owner and the group of the copied file are set to current user and group. <br>
>      *
>      * <B>Security:</B>
>      * Access is granted, if:
>      * <ul>
>      * <li>the user has access to the project</li>
>      * <li>the user can read the sourceresource</li>
>      * <li>the user can create the destinationresource</li>
>      * <li>the destinationresource doesn't exist</li>
>      * </ul>
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentGroup The current group of the user.
>      * @param currentProject The current project of the user.
>      * @param source The complete path of the sourcefile.
>      * @param destination The complete path to the destination.
>      *
>      * @throws CmsException  Throws CmsException if operation was not succesful.
>      */
>     public void copyFile(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject, 
>                          String source, String destination)
>         throws CmsException {
> 
>         // the name of the new file.
>         String filename;
>         // the name of the folder.
>         String foldername;
> 
>         // checks, if the destinateion is valid, if not it throws a exception
>         validFilename(destination.replace('/', 'a'));
> 
>         // read the source-file, to check readaccess
>         CmsResource file = readFileHeader(currentUser, currentProject, source);
> 
>         // split the destination into file and foldername
>         if (destination.endsWith("/")) {
>             filename = file.getName();
>             foldername = destination;
>         }else{
>             foldername = destination.substring(0, destination.lastIndexOf("/")+1);
>             filename = destination.substring(destination.lastIndexOf("/")+1,
>                                              destination.length());
>         }
> 
>         CmsFolder cmsFolder = readFolder(currentUser,currentProject, foldername);
>         if( accessCreate(currentUser, currentProject, (CmsResource)cmsFolder) ) {
>             if(( accessOther(file, C_ACCESS_PUBLIC_WRITE) ||
>                 accessOwner(currentUser, currentProject, file, C_ACCESS_OWNER_WRITE) ||
>                 accessGroup(currentUser, currentProject, file, C_ACCESS_GROUP_WRITE) )){
>                 // write-acces  was granted - copy the file and the metainfos
>                 CmsFile destinationFile = m_dbAccess.copyFile(currentProject, onlineProject(currentUser, currentProject),
>                               currentUser.getId(),source,cmsFolder.getResourceId(), foldername + filename);
> 
>                 this.clearResourceCache(foldername + filename, currentProject, currentUser);
>                 // copy the metainfos
>                 lockResource(currentUser, currentProject, destination, true);
>                 destinationFile.setLocked(currentUser.getId());
>                 destinationFile.setLockedInProject(currentProject.getId());
>                 writeProperties(currentUser,currentProject, destination,
>                     readProperties(currentUser, currentProject, file.getResourceName(), null, false));
>                 // set user and group to currentUser (otherwise the currentUser could not change it
>                 // because the copy is also owned by source owner).
>                 // we cannot use chown/chgrp here because of access checks!
>                 destinationFile.setUserId(currentUser.getId());
>                 destinationFile.setGroupId(currentGroup.getId());
>                 m_dbAccess.writeFileHeader(currentProject, destinationFile, true, currentUser.getId());
>                 this.clearResourceCache(filename, currentProject, currentUser);
>                 m_accessCache.clear();
>                 // inform about the file-system-change
>                 fileSystemChanged(file.isFolder());
>             } else {
>                 throw new CmsException("[" + this.getClass().getName() + "] " + source,
>                     CmsException.C_NO_ACCESS);
>             }
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + destination,
>                 CmsException.C_NO_ACCESS);
>         }
>     }
> 
> - change method copyFolder
> old version:
>      /**
>      * Copies a folder in the Cms. <br>
>      *
>      * <B>Security:</B>
>      * Access is granted, if:
>      * <ul>
>      * <li>the user has access to the project</li>
>      * <li>the user can read the sourceresource</li>
>      * <li>the user can create the destinationresource</li>
>      * <li>the destinationresource doesn't exist</li>
>      * </ul>
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param source The complete path of the sourcefolder.
>      * @param destination The complete path to the destination.
>      *
>      * @throws CmsException  Throws CmsException if operation was not succesful.
>      */
>     public void copyFolder(CmsUser currentUser, CmsProject currentProject,
>                            String source, String destination)
>         throws CmsException {
> 
>         // the name of the folder.
>         String foldername;
> 
>         // checks, if the destinateion is valid, if not it throws a exception
>         validFilename(destination.replace('/', 'a'));
>         foldername = destination.substring(0, destination.substring(0,destination.length()-1).lastIndexOf("/")+1);
>         CmsFolder cmsFolder = readFolder(currentUser,currentProject, foldername);
>         if( accessCreate(currentUser, currentProject, (CmsResource)cmsFolder) ) {
>             // write-acces  was granted - copy the folder and the properties
>             CmsFolder folder=readFolder(currentUser,currentProject,source);
>             // check write access to the folder that has to be copied
>             if(( accessOther((CmsResource)folder, C_ACCESS_PUBLIC_WRITE) ||
>                 accessOwner(currentUser, currentProject, (CmsResource)folder, C_ACCESS_OWNER_WRITE) ||
>                 accessGroup(currentUser, currentProject, (CmsResource)folder, C_ACCESS_GROUP_WRITE) )){
>                 m_dbAccess.createFolder(currentUser,currentProject, onlineProject(currentUser, currentProject), folder,cmsFolder.getResourceId(),destination);
>                 this.clearResourceCache(destination, currentProject, currentUser);
>                 // copy the properties
>                 lockResource(currentUser, currentProject, destination, true);
>                 writeProperties(currentUser,currentProject, destination,
>                             readProperties(currentUser, currentProject, folder.getResourceName(), null, false));
>                 m_resourceListCache.clear();
>                 m_accessCache.clear();
>                 // inform about the file-system-change
>                 fileSystemChanged(true);
>             } else {
>                 throw new CmsException("[" + this.getClass().getName() + "] " + source,
>                     CmsException.C_ACCESS_DENIED);
>             }
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + destination,
>                 CmsException.C_ACCESS_DENIED);
>         }
> 
>     }
> 
> new version:
>      /**
>      * Copies a folder in the Cms. <br>
>      * The owner and the group of the copied folder are set to current user and group. <br>
>      *
>      * <B>Security:</B>
>      * Access is granted, if:
>      * <ul>
>      * <li>the user has access to the project</li>
>      * <li>the user can read the sourceresource</li>
>      * <li>the user can create the destinationresource</li>
>      * <li>the destinationresource doesn't exist</li>
>      * </ul>
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentGroup The current group of the user.
>      * @param currentProject The current project of the user.
>      * @param source The complete path of the sourcefolder.
>      * @param destination The complete path to the destination.
>      *
>      * @throws CmsException  Throws CmsException if operation was not succesful.
>      */
>     public void copyFolder(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject,
>                            String source, String destination)
>         throws CmsException {
> 
>         // the name of the folder.
>         String foldername;
> 
>         // checks, if the destinateion is valid, if not it throws a exception
>         validFilename(destination.replace('/', 'a'));
>         foldername = destination.substring(0, destination.substring(0,destination.length()-1).lastIndexOf("/")+1);
>         CmsFolder cmsFolder = readFolder(currentUser,currentProject, foldername);
>         if( accessCreate(currentUser, currentProject, (CmsResource)cmsFolder) ) {
>             // write-acces  was granted - copy the folder and the properties
>             CmsFolder folder=readFolder(currentUser,currentProject,source);
>             // check write access to the folder that has to be copied
>             if(( accessOther((CmsResource)folder, C_ACCESS_PUBLIC_WRITE) ||
>                 accessOwner(currentUser, currentProject, (CmsResource)folder, C_ACCESS_OWNER_WRITE) ||
>                 accessGroup(currentUser, currentProject, (CmsResource)folder, C_ACCESS_GROUP_WRITE) )){
>                 // Check if folder already exists before trying to create it
>                 CmsFolder destinationFolder=null;
>                 try {
>                     destinationFolder = readFolder(currentUser,currentProject,destination);
>                 } catch (CmsException e) {
>                 }
>                 if (destinationFolder==null) { 
>                     destinationFolder = m_dbAccess.createFolder(currentUser,currentProject, onlineProject(currentUser, currentProject), folder,cmsFolder.getResourceId(),destination);} 
>                 this.clearResourceCache(destination, currentProject, currentUser);
>                 // copy the properties
>                 lockResource(currentUser, currentProject, destination, true);
>                 destinationFolder.setLocked(currentUser.getId());
>                 destinationFolder.setLockedInProject(currentProject.getId());
>                 writeProperties(currentUser,currentProject, destination,
>                             readProperties(currentUser, currentProject, folder.getResourceName(), null, false));
>                 // set user and group to currentUser (otherwise the currentUser could not change it
>                 // because the copy is also owned by source owner).
>                 // we cannot use chown/chgrp here because of access checks!
>                 destinationFolder.setUserId(currentUser.getId());
>                 destinationFolder.setGroupId(currentGroup.getId());
>                 m_dbAccess.writeFolder(currentProject, destinationFolder, true, currentUser.getId());
>                 this.clearResourceCache(destination, currentProject, currentUser);
> 
>                 m_resourceListCache.clear();
>                 m_accessCache.clear();
>                 // inform about the file-system-change
>                 fileSystemChanged(true);
>             } else {
>                 throw new CmsException("[" + this.getClass().getName() + "] " + source,
>                     CmsException.C_ACCESS_DENIED);
>             }
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + destination,
>                 CmsException.C_ACCESS_DENIED);
>         }
> 
>     }
> 
> - change method moveFile:
> old version:
>     /**
>      * Moves the file.
>      *
>      * This operation includes a copy and a delete operation. These operations
>      * are done with their security-checks.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param source The complete path of the sourcefile.
>      * @param destination The complete path of the destinationfile.
>      *
>      * @throws CmsException will be thrown, if the file couldn't be moved.
>      * The CmsException will also be thrown, if the user has not the rights
>      * for this resource.
>      */
>     public void moveFile(CmsUser currentUser, CmsProject currentProject, String source, String destination) throws CmsException {
> 
>         // read the file to check access
>         CmsResource file = readFileHeader(currentUser,currentProject, source);
> 
>         // has the user write-access?
>         if (accessWrite(currentUser, currentProject, file)) {
> 
>             // first copy the file, this may ends with an exception
>             copyFile(currentUser, currentProject, source, destination);
> 
>             // then delete the source-file, this may end with an exception
>             // => the file was only copied, not moved!
>             deleteFile(currentUser, currentProject, source);
>             // inform about the file-system-change
>             fileSystemChanged(file.isFolder());
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + source, CmsException.C_NO_ACCESS);
>         }
>     }
> 
> new version:
>     /**
>      * Moves the file.
>      *
>      * This operation includes a copy and a delete operation. These operations
>      * are done with their security-checks.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentGroup The current group of the user.
>      * @param currentProject The current project of the user.
>      * @param source The complete path of the sourcefile.
>      * @param destination The complete path of the destinationfile.
>      *
>      * @throws CmsException will be thrown, if the file couldn't be moved.
>      * The CmsException will also be thrown, if the user has not the rights
>      * for this resource.
>      */
>     public void moveFile(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject, String source, String destination) throws CmsException {
> 
>         // read the file to check access
>         CmsResource file = readFileHeader(currentUser,currentProject, source);
> 
>         // has the user write-access?
>         if (accessWrite(currentUser, currentProject, file)) {
> 
>             // first copy the file, this may ends with an exception
>             copyFile(currentUser, currentGroup, currentProject, source, destination);
> 
>             // then delete the source-file, this may end with an exception
>             // => the file was only copied, not moved!
>             deleteFile(currentUser, currentProject, source);
>             // inform about the file-system-change
>             fileSystemChanged(file.isFolder());
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + source, CmsException.C_NO_ACCESS);
>         }
>     }
> 
> - change method renameFile
> old version:
>     /**
>      * Renames the file to a new name. <br>
>      *
>      * Rename can only be done in an offline project. To rename a file, the following
>      * steps have to be done:
>      * <ul>
>      * <li> Copy the file with the oldname to a file with the new name, the state
>      * of the new file is set to NEW (2).
>      * <ul>
>      * <li> If the state of the original file is UNCHANGED (0), the file content of the
>      * file is read from the online project. </li>
>      * <li> If the state of the original file is CHANGED (1) or NEW (2) the file content
>      * of the file is read from the offline project. </li>
>      * </ul>
>      * </li>
>      * <li> Set the state of the old file to DELETED (3). </li>
>      * </ul>
>      *
>      * <B>Security:</B>
>      * Access is granted, if:
>      * <ul>
>      * <li>the user has access to the project</li>
>      * <li>the user can write the resource</li>
>      * <li>the resource is locked by the callingUser</li>
>      * </ul>
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param oldname The complete path to the resource which will be renamed.
>      * @param newname The new name of the resource (CmsUser callingUser, No path information allowed).
>      *
>      * @throws CmsException  Throws CmsException if operation was not succesful.
>      */
>     public void renameFile(CmsUser currentUser, CmsProject currentProject, String oldname, String newname) throws CmsException {
>     
>         // read the old file
>         CmsResource file = readFileHeader(currentUser, currentProject, oldname);
>     
>         // checks, if the newname is valid, if not it throws a exception
>         validFilename(newname);
>     
>         // has the user write-access?
>         if (accessWrite(currentUser, currentProject, file)) {
>             String path = oldname.substring(0, oldname.lastIndexOf("/") + 1);
>             copyFile(currentUser, currentProject, oldname, path + newname);
>             deleteFile(currentUser, currentProject, oldname);
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + oldname, CmsException.C_NO_ACCESS);
>         }
>     }
> 
> new version:
>     /**
>      * Renames the file to a new name. <br>
>      *
>      * Rename can only be done in an offline project. To rename a file, the following
>      * steps have to be done:
>      * <ul>
>      * <li> Copy the file with the oldname to a file with the new name, the state
>      * of the new file is set to NEW (2).
>      * <ul>
>      * <li> If the state of the original file is UNCHANGED (0), the file content of the
>      * file is read from the online project. </li>
>      * <li> If the state of the original file is CHANGED (1) or NEW (2) the file content
>      * of the file is read from the offline project. </li>
>      * </ul>
>      * </li>
>      * <li> Set the state of the old file to DELETED (3). </li>
>      * </ul>
>      *
>      * <B>Security:</B>
>      * Access is granted, if:
>      * <ul>
>      * <li>the user has access to the project</li>
>      * <li>the user can write the resource</li>
>      * <li>the resource is locked by the callingUser</li>
>      * </ul>
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentGroup The current group of the user.
>      * @param currentProject The current project of the user.
>      * @param oldname The complete path to the resource which will be renamed.
>      * @param newname The new name of the resource (CmsUser callingUser, No path information allowed).
>      *
>      * @throws CmsException  Throws CmsException if operation was not succesful.
>      */
>     public void renameFile(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject, String oldname, String newname) throws CmsException {
>     
>         // read the old file
>         CmsResource file = readFileHeader(currentUser, currentProject, oldname);
>     
>         // checks, if the newname is valid, if not it throws a exception
>         validFilename(newname);
>     
>         // has the user write-access?
>         if (accessWrite(currentUser, currentProject, file)) {
>             String path = oldname.substring(0, oldname.lastIndexOf("/") + 1);
>             copyFile(currentUser, currentGroup, currentProject, oldname, path + newname);
>             deleteFile(currentUser, currentProject, oldname);
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + oldname, CmsException.C_NO_ACCESS);
>         }
>     }
> 
> com.opencms.file.I_CmsResourceBroker
> - add parameter currentGroup to the following methods
> new version:
>     public void copyFile(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject,
>                          String source, String destination)
>         throws CmsException;
>     public void copyFolder(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject,
>                          String source, String destination)
>         throws CmsException;
>     public void moveFile(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject,
>                          String source, String destination)
>         throws CmsException;
>     public void renameFile(CmsUser currentUser, CmsGroup currentGroup, CmsProject currentProject,
>                            String oldname, String newname)
>         throws CmsException;
> 
> com.opencms.file.CmsObject
> - add parameter currentGroup to broker call in the following methods (signature of CmsObject methods remains unchanged)
> new version:
>     protected void doCopyFile(String source, String destination) throws CmsException {
>         m_rb.copyFile(m_context.currentUser(), m_context.currentGroup(), m_context.currentProject(), getSiteRoot(source), getSiteRoot(destination));
>     }
>     protected void doCopyFolder(String source, String destination) throws CmsException {
>         m_rb.copyFolder(m_context.currentUser(), m_context.currentGroup(), m_context.currentProject(), getSiteRoot(source), getSiteRoot(destination));
>     }
>     protected void doMoveFile(String source, String destination) throws CmsException {
>         m_rb.moveFile(m_context.currentUser(), m_context.currentGroup(), m_context.currentProject(), getSiteRoot(source), getSiteRoot(destination));
>     }
>     protected void doRenameFile(String oldname, String newname) throws CmsException {
>         m_rb.renameFile(m_context.currentUser(), m_context.currentGroup(), m_context.currentProject(), getSiteRoot(oldname), newname);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Fix for Bug 348: CmsResourceBroker.readAllFileHeadersForHist throws a CmsException if the 
> resource has been deleted. The method calls readFileHeader to check read access 
> to the resource. This fails if the resource has already been deleted. A method 
> called "forHist" should only access backup resources as they still exists even 
> for deleted files.
> 
> As other forHist methods also do not have an access check, we removed the check here.
> 
> com.opencms.file.genericSql.CmsResourceBroker
> - change method readAllFileHeadersForHist
> old version:
>      public Vector readAllFileHeadersForHist(CmsUser currentUser, CmsProject currentProject,
>                                       String filename)
>          throws CmsException {
>          CmsResource cmsFile = readFileHeader(currentUser,currentProject, filename);
>          if( accessRead(currentUser, currentProject, cmsFile) ) {
> 
>             // access to all subfolders was granted - return the file-history.
>             return(m_dbAccess.readAllFileHeadersForHist(filename));
>         } else {
>             throw new CmsException("[" + this.getClass().getName() + "] " + filename,
>                  CmsException.C_ACCESS_DENIED);
>         }
>      }
> 
> new version:
>      public Vector readAllFileHeadersForHist(CmsUser currentUser, CmsProject currentProject,
>                                       String filename)
>          throws CmsException {
> 
>          return(m_dbAccess.readAllFileHeadersForHist(filename));
>      }
>      
> ---------------------------------------------------------------------------------------------------
> 
> Two different backup versions of a resource are considered equal. CmsBackupResource.equals() should
> not only check the file name but also the version id.
> 
> com.opencms.file.CmsBackupResource:
> - add method equals
>     /**
>      * Compares the overgiven object with this object.
>      * Two CmsBackupResources are considered equal if they have the same absolute resource name
>      * and the same version id.
>      * @return true, if the object is identically else it returns false.
>      */
>     public boolean equals(Object obj) {
>         boolean equal;
>         if (obj instanceof CmsBackupResource) {
>             // parent class checks only resource name, not enough for backups
>             equal=super.equals(obj);
>             if (equal)  {
>                 // same version ID than the current resource?
>                 if (((CmsBackupResource)obj).getVersionId() != m_versionId){
>                     equal = false;
>                 }
>             }
>         } else {
>             equal = false;
>         }
>         
>         return equal;
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Bug 364:
> Trying to send a mail from a scheduled job fails with NullPointerException.
> Reason: CmsMail always tries to get additional attachments from request, that is not available in a scheduled job.
> 
> com.opencms.defaults.CmsMail
> - change method buildMessage
> old version:
>         // Set content and attachments
>         Vector v = new Vector();
>         if (c_CMS != null){
>             Enumeration enum = c_CMS.getRequestContext().getRequest().getFileNames();
>             while(enum.hasMoreElements()) {
>                 v.addElement(enum.nextElement());
>             }
>         }
> 
> new version:
>         // Set content and attachments
>         Vector v = new Vector();
>         if (c_CMS != null && c_CMS.getRequestContext() != null && c_CMS.getRequestContext().getRequest() != null){
>             Enumeration enum = c_CMS.getRequestContext().getRequest().getFileNames();
>             while(enum.hasMoreElements()) {
>                 v.addElement(enum.nextElement());
>             }
>         }
> 
> ---------------------------------------------------------------------------------------------------
> 
> Bug 365
> Access checks for read and visible return a wrong result if the user has these privileges via his group.
> 
> com.opencms.file.genericSql.CmsResourceBroker
> - change method accessReadVisible
> 1st change, old version:
>         if ((resource == null) || !accessProject(currentUser, currentProject, resource.getProjectId()) ||
>             (!accessOther(resource, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE) &&
>              !accessOwner(currentUser, currentProject, resource, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE) &&
>              !accessGroup(currentUser, currentProject, resource, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE))) {
>             return false;
>         }
> 1st change, new version:
>         if ((resource == null) || !accessProject(currentUser, currentProject, resource.getProjectId()) ||
>             (!accessOther(resource, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE) &&
>              !accessOwner(currentUser, currentProject, resource, C_ACCESS_OWNER_READ + C_ACCESS_OWNER_VISIBLE) &&
>              !accessGroup(currentUser, currentProject, resource, C_ACCESS_GROUP_READ + C_ACCESS_GROUP_VISIBLE))) {
>             return false;
>         }
> 
> 2nd change, old version:
>             if (!accessOther(res, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE) &&
>                 !accessOwner(currentUser, currentProject, res, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE) &&
>                 !accessGroup(currentUser, currentProject, res, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE)) {
>                 return false;
>             }
> 2nd change, new version:
>             if (!accessOther(res, C_ACCESS_PUBLIC_READ + C_ACCESS_PUBLIC_VISIBLE) &&
>                 !accessOwner(currentUser, currentProject, res, C_ACCESS_OWNER_READ + C_ACCESS_OWNER_VISIBLE) &&
>                 !accessGroup(currentUser, currentProject, res, C_ACCESS_GROUP_READ + C_ACCESS_GROUP_VISIBLE)) {
>                 return false;
>             }
> 
> ---------------------------------------------------------------------------------------------------
> 
> 
> 
> ------------------------------------------------------------------------
> 
> Enhancements for OpenCms 5.0.1:
> -------------------------------
> 
> This file lists the enhancements made by GETIT GmbH for productional use of OpenCms 5.0.1.
> 
> ---------------------------------------------------------------------------------------------------
> 
> Change the group for a resource recursively from CmsShell:
> 
> com.opencms.coreCmsShellCommands.java, new method:
> 	/**
> 	 * Changes the group for this resource recursively<BR/>
> 	 *
> 	 * The user may change this, if he is admin of the resource.
> 	 *
> 	 * @param filename The complete path to the resource.
> 	 * @param newGroup The new of the new group for this resource.
> 	 * @param recursively shows if the subResources (of a folder) should be changed too.
> 	 */
> 	public void chgrp(String filename, String newGroup, String recursively) {
> 		try {
> 			m_cms.chgrp(filename, newGroup, 
> 				recursively.toLowerCase().equals("true"));
> 		}
> 		catch(Exception exc) {
> 			CmsShell.printException(exc);
> 		}
> 	}
> 
> ---------------------------------------------------------------------------------------------------
> 
> Methods to access a project with a specific name from CmsShell
> In 5.0.1, you can also change to a project if you have its project id. If you create a project
> using CmsShell, you specify its name but you do not know its id. So you cannot do anything with this 
> project later. We added some methods using the name as parameter.
> 
> com.opencms.coreCmsShellCommands.java, new methods:
> 	/**
> 	 * Sets the current project for the user.
> 	 *
> 	 * @param name The name of the project to be set as current.
> 	 *             There should be only one project with this name,
> 	 * 			   otherwise this call sets the first project found.
> 	 */
> 	public void setCurrentProjectWithName(String name) {
> 		try {
> 			
> 			Vector projects = m_cms.getAllAccessibleProjects();
> 			for(int i = 0;i < projects.size();i++) {
> 				CmsProject project = (CmsProject)projects.elementAt(i);
> 				if (project.getName().equals(name)) {
> 					System.out.println(m_cms.getRequestContext()
> 						.setCurrentProject(project.getId()));
> 					break;
> 				}
> 			}			
> 		}
> 		catch(Exception exc) {
> 			CmsShell.printException(exc);
> 		}
> 	}
> 
> 	/**
> 	 * Deletes all projects with a specified name.
> 	 *
> 	* @param name The name of the project to be deleted.
> 	*             There should be only one project with this name,
> 	* 			  otherwise this call deletes all projects found!
> 	*/
> 	public void deleteProjectWithName(String name) {
> 		try {
> 			Vector projects = m_cms.getAllAccessibleProjects();
> 			for(int i = 0;i < projects.size();i++) {
> 				CmsProject project = (CmsProject)projects.elementAt(i);
> 				if (project.getName().equals(name)) {
> 					m_cms.deleteProject(project.getId());
> 				}
> 			}
> 		}
> 		catch(Exception exc) {
> 			CmsShell.printException(exc);
> 		}
> 	}
> 
> 
> ---------------------------------------------------------------------------------------------------
> 
> Methods to read properties from a backup version for a resource:
> 
> com.opencms.file.genericSql.CmsDbAccess:
> - new method:
>     /**
>      * Returns a list of all history properties of a file or folder.<p>
>      *
>      * @param resourceId the id of the resource
>      * @param resource the resource to read the properties from
>      * @param resourceType the type of the resource
>      *
>      * @return a Map of Strings representing the properties of the resource
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public HashMap readPropertiesForHist(CmsResource resource, int resourceType)
>         throws CmsException {
> 
>         HashMap returnValue = new HashMap();
>         ResultSet result = null;
>         PreparedStatement statement = null;
>         Connection con = null;
>         String usedPool;
>         int resourceId = resource.getResourceId();
>         //int onlineProject = getOnlineProject(projectId).getId();
>         usedPool = m_poolNameBackup;
>         try {
>            con = DriverManager.getConnection(usedPool);
>             // create project
>             statement = con.prepareStatement(m_cq.get("C_PROPERTIES_READALL_BACKUP"));
>             statement.setInt(1, resourceId);
>             statement.setInt(2, resourceType);
>             result = statement.executeQuery();
>             while(result.next()) {
>                  returnValue.put(result.getString(m_cq.get("C_PROPERTYDEF_NAME")),
>                                  result.getString(m_cq.get("C_PROPERTY_VALUE")));
>             }
>         } catch( SQLException exc ) {
>             throw new CmsException("[" + this.getClass().getName() + "] " + exc.getMessage(),
>                 CmsException.C_SQL_ERROR, exc);
>         } finally {
>             // close all db-resources
>             if(result != null) {
>                 try {
>                     result.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(statement != null) {
>                 try {
>                     statement.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(con != null) {
>                 try {
>                     con.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>         }
>         return(returnValue);
>     }
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - new constant:
>     protected static final String C_CACHE_ALL_BACKUP_PROPERTIES = "__CACHE_ALL_BACKUP_PROPERTIES__";
> 
> - new method:
>     /**
>      * Looks up all properties for a resource with optional direcory upward cascading.<p>
>      * 
>      * 
>      * @param currentUser the current user
>      * @param currentProject the current project of the user
>      * @param resource the resource to look up the property for
>      * @param siteRoot the current site root
>      * @param search if <code>true</code>, the properties will also be looked up on all parent folders
>      *   and the results will be merged, if <code>false</code> not (ie. normal property lookup)
>      * @return Map of Strings representing all properties of the resource
>      * @throws CmsException in case there where problems reading the properties
>      */
>     public Map readPropertiesForHist(CmsUser currentUser, CmsProject currentProject, String resource, String siteRoot, boolean search, int version_id) 
>     throws CmsException {
>         // read the resource from history
>         CmsResource res = readFileForHist (currentUser, currentProject, version_id,resource);
>         
>         search = search && (siteRoot != null);
>         // check if we have the result already cached
>         HashMap value = null;
>         
>         String cacheKey = getCacheKey(C_CACHE_ALL_BACKUP_PROPERTIES + search+version_id, null, new CmsProject(currentProject.getId(), -1), res.getResourceName());
>         value = (HashMap)m_propertyCache.get(cacheKey);
>         
>         if (value == null) {
>             // result not cached, let's look it up in the DB
>             if (search) {
>                 boolean cont;
>                 siteRoot += "/";
>                 value = new HashMap();
>                 HashMap parentValue;
>                 do {
>                     parentValue = (HashMap)readProperties(currentUser, currentProject, resource, siteRoot, false);
>                     parentValue.putAll(value);
>                     value.clear();
>                     value.putAll(parentValue);
>                     resource = CmsResource.getParent(resource);
>                     cont = (! siteRoot.equals(resource));
>                 } while (cont);
>             } else {
>                 value = m_dbAccess.readPropertiesForHist(res, res.getType());
>             }  
>             // store the result in the cache
>             m_propertyCache.put(cacheKey, value);
>         }
>         return (Map)value.clone();
>     }    
> 
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Looks up all properties from ab backup resource with optional direcory upward cascading.<p>
>      * 
>      * <b>Security:</b>
>      * Only a user is granted who has the right to read the resource.
>      * 
>      * @param currentUser the current user
>      * @param currentProject the current project of the user
>      * @param resource the resource to look up the property for
>      * @param siteroot the site root where to stop the cascading
>      * @param search if <code>true</code>, the properties will also be looked up on all parent folders
>      *   and the results will be merged, if <code>false</code> not (ie. normal property lookup)
>      * @param versionId the version id containing the defined properties
>      * @return Map of Strings representing all properties of the resource
>      * @throws CmsException in case there where problems reading the properties
>      */
> 	public Map readPropertiesForHist(CmsUser currentUser, CmsProject currentProject, String resource, String siteRoot, boolean search, int versionId) throws CmsException;    
> 
> com.opencms.file.CmsObject:
> - new method:
>     /**
>      * Looks up all properties for a resource.<p>
>      * 
>      * @param resource the resource to look up the property for
>      * @param versionId the requeste version of the resource
>      * @return Map of Strings representing all properties of the resource
>      * @throws CmsException in case there where problems reading the properties
>      */  
>     public Map readProperties(String resource,int versionId) throws CmsException {
>     	return m_rb.readPropertiesForHist(m_context.currentUser(), m_context.currentProject(), m_context.getSiteRoot(resource), m_context.getSiteRoot(), false,versionId);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> CmsSetupUtils cannot read Property values containing a comma. We enhanced the class to read commas when escaped as \,
> 
> com.opencms.boot.CmsSetupUtils:
> - change method splitMultipleValues:
> old version:
>     private String splitMultipleValues(String value)  {
>       String tempValue = "";
>       StringTokenizer st = new StringTokenizer(value,",");
>       int counter = 1;
>       int max = st.countTokens();
>       while(st.hasMoreTokens()) {
>         tempValue += st.nextToken().trim();
>         if(counter < max)  {
>           tempValue += ", \\ \n";
>         }
>         counter++;
>       }
>       return tempValue;
>     }
> new version:
>     private String splitMultipleValues(String value)  {
>         StringBuffer tmp = new StringBuffer();
>         int start = 0;
>         int stop = -1;
>         while (stop<value.length()) {
>             stop = value.indexOf(',',stop+1);
>             while (stop>=1 && value.charAt(stop-1)=='\\') {
>                 stop = value.indexOf(',',stop+1);
>             }
>             if (stop==-1) stop=value.length();
>             tmp.append(value.substring(start,stop).trim());
>             if (stop<value.length()) tmp.append(", \\ \n");
>             start=stop+1;
>         }
>         return tmp.toString();
>     }
>     
> ---------------------------------------------------------------------------------------------------
> 
> Functionality for users to be logged in without a password. Can be used in scheduled jobs.
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - new method:
> 
>     /**
>      * Logs a user into the Cms, if the password is correct.
>      *
>      * <B>Security</B>
>      * All users are granted.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param username The name of the user to be returned.
>      * @param password The password of the user to be returned.
>      * @return the logged in user.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public CmsUser loginUser(CmsUser currentUser, CmsProject currentProject,
>                                String username)
>         throws CmsException {
> 
>         // we must read the user from the dbAccess to avoid the cache
>         CmsUser newUser = m_dbAccess.readUser(username , C_USER_TYPE_SYSTEMUSER);
> 
>         // is the user enabled?
>         if( newUser.getFlags() == C_FLAG_ENABLED ) {
>             // Yes - log him in!
>             // first write the lastlogin-time.
>             newUser.setLastlogin(new Date().getTime());
>             // write the user back to the cms.
>             m_dbAccess.writeUser(newUser);
>             // update cache
>             m_userCache.put(new CacheId(newUser), newUser);
>             return(newUser);
>         } else {
>             // No Access!
>             throw new CmsException("[" + this.getClass().getName() + "] " + username,
>                 CmsException.C_NO_ACCESS );
>         }
>     }    
>     
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Logs a user into the Cms, no password is needed.
>      *
>      * <B>Security</B>
>      * All users are granted.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param username The name of the user to be returned.
>      * @return the logged in user.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public CmsUser loginUser(CmsUser currentUser, CmsProject currentProject,
>                                String username)
>         throws CmsException;        
> 
> com.opencms.file.CmsObject:
> - new method:
> /**
>  * Logs a user into the Cms withou providing a password
>  *
>  * @param username the name of the user.
>  * @return the name of the logged in user.
>  *
>  * @throws CmsException if operation was not successful
>  */
> public String loginUser(String username) throws CmsException {
>     // login the user
>     CmsUser newUser = m_rb.loginUser(m_context.currentUser(), m_context.currentProject(), username);
>     // init the new user
>     init(m_rb, m_context.getRequest(), m_context.getResponse(), newUser.getName(), newUser.getDefaultGroup().getName(), C_PROJECT_ONLINE_ID, m_context.isStreaming(), m_context.getElementCache(), m_sessionStorage, m_context.getDirectoryTranslator(), m_context.getFileTranslator());
> 
>     this.fireEvent(com.opencms.flex.I_CmsEventListener.EVENT_LOGIN_USER, newUser);
> 
>     // return the user-name
>     this.fireEvent(com.opencms.flex.I_CmsEventListener.EVENT_LOGIN_USER, newUser);
>     return (newUser.getName());
> }
>         
> ---------------------------------------------------------------------------------------------------
> 
> Workplace Popup for folder tree always starts with root folder. We added a parameter to specify another root folder.
> 
> com.opencms.workplace.I_CmsWpConstants:
> - new constant:
>     /** Parameter for rootfolder  */
>     public static final String C_PARA_ROOTFOLDER = "rootfolder";
> 
> com.opencms.workplace.CmsFolderTree:
> - change method getTree:
> old version:
>         // get current and root folder
>         rootFolder = cms.rootFolder().getAbsolutePath();
> 
> new version:
>         // get current and root folder
>         rootFolder = cms.getRequestContext().getRequest().getParameter(C_PARA_ROOTFOLDER);
>         if ((rootFolder == null) || (rootFolder.equals("")))
>         	rootFolder = cms.rootFolder().getAbsolutePath();
> 
> 
> ---------------------------------------------------------------------------------------------------
> 
> You cannot get a specific project by its name.
> 
> com.opencms.file.CmsObject:
> - new method:
>     /**
> 	 * Get project id of the project with the given name
> 	 * 
> 	 * @param name     The name of the project to be set as current. There should be
> 	 *                  only one project with this name, otherwise this call sets the
> 	 *                  first project found.
>      * @return         The ID of the project if found, -1 if not
> 	 */
> 	public int getProjectWithName(String name) throws CmsException {
> 		Vector projects = getAllAccessibleProjects();
> 		for (int i = 0; i < projects.size(); i++) {
> 			CmsProject project = (CmsProject) projects.elementAt(i);
> 			if (project.getName().equals(name)) {
> 				return project.getId();
> 			}
> 		}
> 		return -1;
> 	}
>     
> ---------------------------------------------------------------------------------------------------
> 
> If you write a property and the property definition does not exist, you should be able to automatically
> create the definition. Methods for this only exist in DbAccess unreachable for modules.
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - change method writeProperty and add new method with different signature
> old version:
>     /**
>      * Writes a propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation has
>      * to be read.
>      * @param property The propertydefinition-name of which the propertyinformation has to be set.
>      * @param value The value for the propertyinfo to be set.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperty(CmsUser currentUser, CmsProject currentProject,
>                                      String resource, String property, String value)
>         throws CmsException {
> 
>         // read the resource
>         CmsResource res = readFileHeader(currentUser,currentProject, resource);
> 
>         // check the security
>         if( ! accessWrite(currentUser, currentProject, res) ) {
>              throw new CmsException("[" + this.getClass().getName() + "] " + resource,
>                 CmsException.C_NO_ACCESS);
>         }
> 
>         m_dbAccess.writeProperty(property, currentProject.getId(),value, res,res.getType(), false);
>         m_propertyCache.clear();
>         // set the file-state to changed
>         if(res.isFile()){
>             m_dbAccess.writeFileHeader(currentProject, (CmsFile) res, true, currentUser.getId());
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>         } else {
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>             m_dbAccess.writeFolder(currentProject, readFolder(currentUser,currentProject, resource), true, currentUser.getId());
>         }
>         // update the cache
>         this.clearResourceCache(resource, currentProject, currentUser);
>     }
> 
> new version:
>     /**
>      * Writes a propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation has
>      * to be read.
>      * @param property The propertydefinition-name of which the propertyinformation has to be set.
>      * @param value The value for the propertyinfo to be set.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperty(CmsUser currentUser, CmsProject currentProject,
>                                      String resource, String property, String value)
>         throws CmsException {
>         writeProperty(currentUser, currentProject, resource, property, value, false);
>     }
> 
>     /**
>      * Writes a propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation has
>      * to be read.
>      * @param property The propertydefinition-name of which the propertyinformation has to be set.
>      * @param value The value for the propertyinfo to be set.
>      * @param addDefinition If <code>true</code> then the propertydefinition is added if it not exists
>      * 
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperty(CmsUser currentUser, CmsProject currentProject,
>                                      String resource, String property, String value, boolean addDefinition)
>         throws CmsException {
> 
>         // read the resource
>         CmsResource res = readFileHeader(currentUser,currentProject, resource);
> 
>         // check the security
>         if( ! accessWrite(currentUser, currentProject, res) ) {
>              throw new CmsException("[" + this.getClass().getName() + "] " + resource,
>                 CmsException.C_NO_ACCESS);
>         }
> 
>         m_dbAccess.writeProperty(property, currentProject.getId(),value, res,res.getType(), addDefinition);
>         m_propertyCache.clear();
>         // set the file-state to changed
>         if(res.isFile()){
>             m_dbAccess.writeFileHeader(currentProject, (CmsFile) res, true, currentUser.getId());
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>         } else {
>             if (res.getState()==C_STATE_UNCHANGED) {
>                 res.setState(C_STATE_CHANGED);
>             }
>             m_dbAccess.writeFolder(currentProject, readFolder(currentUser,currentProject, resource), true, currentUser.getId());
>         }
>         // update the cache
>         this.clearResourceCache(resource, currentProject, currentUser);
>     }
> 
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Writes a propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation has
>      * to be read.
>      * @param property The propertydefinition-name of which the propertyinformation has to be set.
>      * @param value The value for the propertyinfo to be set.
>      * @param addDefinition If <code>true</code> then the propertydefinition is added if it not exists
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperty(CmsUser currentUser, CmsProject currentProject,
>                                      String resource, String property, String value, boolean addDefinition)
>         throws CmsException;
> 
> com.opencms.file.CmsObject:
> - new method:
>     /**
>      * Writes a property for a file or folder.
>      *
>      * @param name the resource-name for which the property will be set.
>      * @param property the property-definition name.
>      * @param value the value for the property to be set.
>      * @param addDefinition If <code>true</code> then the propertydefinition is added if it not exists
>      *
>      * @throws CmsException if operation was not successful.
>      */
>     public void writeProperty(String name, String property, String value, boolean addDefinition) throws CmsException {
>         m_rb.writeProperty(m_context.currentUser(), m_context.currentProject(), getSiteRoot(name), property, value, addDefinition);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> If you write some properties and any of the property definitions does not exist, you should be able to automatically
> create the definition. Methods for this only exist in DbAccess unreachable for modules.
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - change method writeProperties and add new method with different signature
> old version:
>     /**
>      * Writes a couple of propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation
>      * has to be read.
>      * @param propertyinfos A Hashtable with propertydefinition- propertyinfo-pairs as strings.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperties(CmsUser currentUser, CmsProject currentProject,
>                                       String resource, Map propertyinfos)
>         throws CmsException {
>         // read the resource
> 
> 
>         CmsResource res = readFileHeader(currentUser,currentProject, resource);
> 
>         // check the security
>         if( ! accessWrite(currentUser, currentProject, res) ) {
>              throw new CmsException("[" + this.getClass().getName() + "] " + resource,
>                 CmsException.C_NO_ACCESS);
>         }
> 
>         m_dbAccess.writeProperties(propertyinfos, currentProject.getId(), res, res.getType());
>         m_propertyCache.clear();
>         if (res.getState()==C_STATE_UNCHANGED) {
>             res.setState(C_STATE_CHANGED);
>         }
>         if(res.isFile()){
>             m_dbAccess.writeFileHeader(currentProject, (CmsFile) res, false, currentUser.getId());
>         } else {
>             m_dbAccess.writeFolder(currentProject, readFolder(currentUser,currentProject, resource), false, currentUser.getId());
>         }
>         // update the cache
>         this.clearResourceCache(resource, currentProject, currentUser);
>     }
> 
> new version:
>     /**
>      * Writes a couple of propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation
>      * has to be read.
>      * @param propertyinfos A Hashtable with propertydefinition- propertyinfo-pairs as strings.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperties(CmsUser currentUser, CmsProject currentProject,
>                                       String resource, Map propertyinfos)
>         throws CmsException {
>             writeProperties(currentUser, currentProject, resource, propertyinfos, false);
>     }
>     
>     /**
>      * Writes a couple of propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation
>      * has to be read.
>      * @param propertyinfos A Hashtable with propertydefinition- propertyinfo-pairs as strings.
>      * @param addDefinition If <code>true</code> then the propertydefinition is added if it not exists
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperties(CmsUser currentUser, CmsProject currentProject,
>                                       String resource, Map propertyinfos, boolean addDefinition)
>         throws CmsException {
>         // read the resource
> 
> 
>         CmsResource res = readFileHeader(currentUser,currentProject, resource);
> 
>         // check the security
>         if( ! accessWrite(currentUser, currentProject, res) ) {
>              throw new CmsException("[" + this.getClass().getName() + "] " + resource,
>                 CmsException.C_NO_ACCESS);
>         }
> 
>         m_dbAccess.writeProperties(propertyinfos, currentProject.getId(), res, res.getType(), addDefinition);
>         m_propertyCache.clear();
>         if (res.getState()==C_STATE_UNCHANGED) {
>             res.setState(C_STATE_CHANGED);
>         }
>         if(res.isFile()){
>             m_dbAccess.writeFileHeader(currentProject, (CmsFile) res, false, currentUser.getId());
>         } else {
>             m_dbAccess.writeFolder(currentProject, readFolder(currentUser,currentProject, resource), false, currentUser.getId());
>         }
>         // update the cache
>         this.clearResourceCache(resource, currentProject, currentUser);
>     }
> 
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Writes a couple of propertyinformation for a file or folder.
>      *
>      * <B>Security</B>
>      * Only the user is granted, who has the right to write the resource.
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resource The name of the resource of which the propertyinformation
>      * has to be read.
>      * @param propertyinfos A Hashtable with propertydefinition- propertyinfo-pairs as strings.
>      * @param addDefinition If <code>true</code> then the propertydefinition is added if it not exists
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public void writeProperties(CmsUser currentUser, CmsProject currentProject,
>                                       String resource, Map propertyinfos, boolean addDefinition)
>         throws CmsException;
> 
> com.opencms.file.CmsObject:
> - new method:
> /**
>  * Writes a couple of Properties for a file or folder.
>  *
>  * @param name the resource-name of which the Property has to be set.
>  * @param properties a Hashtable with property-definitions and property values as Strings.
>  * @param addDefinition If <code>true</code> then the propertydefinition is added if it not exists
>  *
>  * @throws CmsException if operation was not successful.
>  */
> public void writeProperties(String name, Map properties, boolean addDefinition) throws CmsException {
>     m_rb.writeProperties(m_context.currentUser(), m_context.currentProject(), getSiteRoot(name), properties, addDefinition);
> }
> 
> 
> ---------------------------------------------------------------------------------------------------
> 
> We missed a method to find a folder with a specific name searching only through a part of VFS. As relative folder names are not unique, 
> the following method returns only the first folder found.
> 
> com.opencms.file.genericSql.query.properties:
> - add properties:
> C_RESOURCES_FIND_FIRST_FOLDER_1=SELECT CMS_RESOURCES.RESOURCE_NAME \
>                      FROM CMS_RESOURCES, CMS_PROJECTRESOURCES \
>                      WHERE CMS_RESOURCES.RESOURCE_NAME LIKE '
> C_RESOURCES_FIND_FIRST_FOLDER_2=' AND CMS_RESOURCES.RESOURCE_TYPE = 0 \
>                      AND CMS_RESOURCES.RESOURCE_NAME LIKE CONCAT(CMS_PROJECTRESOURCES.RESOURCE_NAME,'%') \
>                      AND CMS_PROJECTRESOURCES.PROJECT_ID IN (?, 1) \
>                      ORDER BY CMS_RESOURCES.RESOURCE_NAME, CMS_PROJECTRESOURCES.PROJECT_ID DESC
> C_RESOURCES_FIND_FIRST_FOLDER_1_ONLINE=SELECT CMS_ONLINE_RESOURCES.RESOURCE_NAME \
>                         FROM CMS_ONLINE_RESOURCES \
>                         WHERE RESOURCE_NAME LIKE '
> C_RESOURCES_FIND_FIRST_FOLDER_2_ONLINE=' AND PROJECT_ID = ?
> 
> 
> com.opencms.file.genericSql.CmsDbAccess:
> - new method:
>     /**
>      * Searches for a vfs folder with a specific relative name.
>      * @param project          The project in which the resource will be used.
>      * @param folderName       relative name of a vfs folder
>      * @param rootFolderName   absolute vfs name of the folder to search in
>      * @return absolute name of the first folder found recursively under rootFolderName which name is folderName
>      *         null if no folder found
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public String getFirstFolderWithName(CmsProject project, String folderName, String rootFolderName)
>         throws CmsException {
> 
>         ResultSet res = null;
>         PreparedStatement statement = null;
>         Connection con = null;
>         String usedPool;
>         String usedStatement;
>         String resourcename = rootFolderName + "%" + folderName;
>         String absolutename = null;
>         int onlineProject = I_CmsConstants.C_PROJECT_ONLINE_ID;
>         if (project.getId() == onlineProject){
>             usedPool = m_poolNameOnline;
>             usedStatement = "_ONLINE";
>         } else {
>             usedPool = m_poolName;
>             usedStatement = "";
>         }
>         try {
>             con = DriverManager.getConnection(usedPool);
>             // read resource data from database
>             statement = con.prepareStatement(m_cq.get("C_RESOURCES_FIND_FIRST_FOLDER_1"+usedStatement)+"/default/vfs"+resourcename+m_cq.get("C_RESOURCES_FIND_FIRST_FOLDER_2"+usedStatement));
>             statement.setInt(1,project.getId());
>             res = statement.executeQuery();
>             // get resource name from first resource in the result
>             if(res.next()) {
>                 absolutename=res.getString(m_cq.get("C_RESOURCES_RESOURCE_NAME"));
>                 if (absolutename.startsWith("/default/vfs")) {
>                     absolutename = absolutename.substring("/default/vfs".length());
>                 }
>             }
>         } catch (SQLException e){
>             throw new CmsException("["+this.getClass().getName()+"]"+e.getMessage(),CmsException.C_SQL_ERROR, e);
>         } catch (Exception ex) {
>             throw new CmsException("["+this.getClass().getName()+"]", ex);
>         } finally {
>             // close all db-resources
>             if(res != null) {
>                 try {
>                     res.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(statement != null) {
>                 try {
>                     statement.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(con != null) {
>                 try {
>                     con.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>         }
>         return absolutename;
>     }
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - new method:
>     /**
>      * Searches for a vfs folder with a specific relative name.
>      * @param currentUser      ignored in this method
>      * @param currentProject   The project in which the resource will be used.
>      * @param folderName       relative name of a vfs folder
>      * @param rootFolderName   absolute vfs name of the folder to search in
>      * @return absolute name of the first folder found recursively under rootFolderName which name is folderName
>      *         null if no folder found
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public String getFirstFolderWithName(CmsUser currentUser, CmsProject currentProject, String folderName, String rootFolderName) throws CmsException {
>         return m_dbAccess.getFirstFolderWithName(currentProject, folderName, rootFolderName);
>     }
>     
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Searches for a vfs folder with a specific relative name.
>      * @param currentUser      ignored in this method
>      * @param currentProject   The project in which the resource will be used.
>      * @param folderName       relative name of a vfs folder
>      * @param rootFolderName   absolute vfs name of the folder to search in
>      * @return absolute name of the first folder found recursively under rootFolderName which name is folderName
>      *         null if no folder found
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public String getFirstFolderWithName(CmsUser currentUser, CmsProject currentProject, String folderName, String rootFolderName) throws CmsException;
> 
> com.opencms.file.CmsObject:
> - new method:
>     /**
>      * Searches for a vfs folder with a specific relative name.
>      * @param folderName       relative name of a vfs folder
>      * @param rootFolderName   absolute vfs name of the folder to search in
>      * @return absolute name of the first folder found recursively under rootFolderName which name is folderName
>      *         null if no folder found
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public String getFirstFolderWithName(String folderName, String rootFolderName) throws CmsException {
>         return m_rb.getFirstFolderWithName(m_context.currentUser(), m_context.currentProject(), folderName, rootFolderName);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> We added a method to find all resources in a folder that have been published after a specific date.
> This only works if backup is enabled cause a resource's publish date is only stored in the backup resource.
> 
> com.opencms.file.genericSql.query.properties:
> - add properties:
> # all resources that match a filter and have been published afer a specified date
> # only works correct if backup is enabled cause otherwise no publish date is saved
> C_SELECT_LAST_PUBLISHED_RESOURCES=SELECT DISTINCT RESOURCE_NAME \
>     FROM CMS_BACKUP_RESOURCES \
>     WHERE TO_CHAR(DATE_CREATED, 'YYYY-MM-DD HH24:MI:SS') > ? \
>     AND RESOURCE_NAME LIKE ?
>     ORDER BY RESOURCE_NAME
> 
> com.opencms.file.mySql.query.properties:
> C_SELECT_LAST_PUBLISHED_RESOURCES=SELECT DISTINCT RESOURCE_NAME \
>     FROM CMS_BACKUP_RESOURCES \
>     WHERE DATE_CREATED > ? \
>     AND RESOURCE_NAME LIKE ?
>     ORDER BY RESOURCE_NAME
> 
> com.opencms.file.genericSql.CmsDbAccess:
> - new imports:
> import java.text.SimpleDateFormat;
> import java.util.Date;
> import java.util.GregorianCalendar;
> 
> - new method:
>     /**
>      * select the names of all resources that have been published after a specific time
>      * and belong to a specific root folder
>      *
>      * @param startDate a date
>      * @param folderName absolute name of a VFS folder
>      * @return a collection of all resource names from resources 
>      * @author Sven Bonorden, GETIT GmbH
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public Vector getLastPublishedResources(Date startDate, String folderName) throws CmsException {
>         if (startDate == null) {
>            GregorianCalendar cal = new GregorianCalendar(1970,1,1);
>            startDate = new Date(cal.getTimeInMillis());
>         }
>         String startDateString = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(startDate);
>         
>         if (folderName == null || folderName.length()==0) {
>            folderName = "";
>         }
>         if (!folderName.startsWith("/default/vfs")) {
>             folderName = "/default/vfs" + folderName;
>         }
>         
>         Connection con = null;
>         PreparedStatement statement = null;
>         ResultSet res = null;
>         Vector publishedResources = new Vector();
>         try {
>             con = DriverManager.getConnection(m_poolNameBackup);
>             statement = con.prepareStatement(m_cq.get("C_SELECT_LAST_PUBLISHED_RESOURCES"));
> 
>             statement.setString(1, startDateString);
>             statement.setString(2, folderName + "%");
>             
>             res = statement.executeQuery();
>             while (res.next()) {
>                 publishedResources.addElement(res.getString("RESOURCE_NAME"));
>             }
>             res.close();
>         } catch (SQLException e) {
>             throw new CmsException("[" + this.getClass().getName() + "] " + e.getMessage(), CmsException.C_SQL_ERROR, e);
>         } finally {
>             if (statement != null) {
>                 try{
>                     statement.close();
>                 } catch (SQLException e){
>                 }
>             }
>             if (con != null) {
>                 try{
>                     con.close();
>                 } catch (SQLException e){
>                 }
>             }
>         }
>         return publishedResources;
>     }
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - new method:
>     /**
>      * select the names of all resources that have been published after a specific time
>      * and belong to a specific root folder
>      *
>      * @param startDate a date
>      * @param folderName absolute name of a VFS folder
>      * @return a collection of all resource names from resources 
>      * @author Sven Bonorden, GETIT GmbH
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public Vector getLastPublishedResources(Date startDate, String folderName) throws CmsException {
>         return m_dbAccess.getLastPublishedResources(startDate, folderName);
>     }
> 
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * select the names of all resources that have been published after a specific time
>      * and belong to a specific root folder
>      *
>      * @param startDate a date
>      * @param folderName absolute name of a VFS folder
>      * @return a collection of all resource names from resources 
>      * @author Sven Bonorden, GETIT GmbH
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public Vector getLastPublishedResources(Date startDate, String folderName) 
>         throws CmsException;
> 
> com.opencms.file.CmsObject:
> - new method:
>     /**
>      * Select the names of all resources that have been published after a specific time
>      * and belong to a specific root folder.
>      * This method ignores access priviledges and projects, all published files are returned. 
>      *
>      * @param startDate a date
>      * @param folderName absolute name of a VFS folder
>      * @return a collection of all resource names from resources 
>      * @author Sven Bonorden, GETIT GmbH
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public Vector getLastPublishedResources(Date startDate, String folderName) throws CmsException {
>         return m_rb.getLastPublishedResources(startDate, folderName);
>     }
> 
> ---------------------------------------------------------------------------------------------------
> 
> It was impossible to get the resource type of a deleted resource (that is still available in the backup). 
> 
> com.opencms.file.genericSql.query.properties:
> - add properties:
> C_RESOURCES_READ_ALL_BACKUP_ORDER_DESC=SELECT CMS_BACKUP_RESOURCES.*, CMS_BACKUP_RESOURCES.PROJECT_ID LOCKED_IN_PROJECT \
>                             FROM CMS_BACKUP_RESOURCES WHERE RESOURCE_NAME=?  \
>                             ORDER BY VERSION_ID DESC
> 
> com.opencms.file.genericSql.CmsDbAccess:
> - new method:
>     /**
>      * Reads the resource type of a historic file in the OpenCms.<BR>
>      * 
>      * @param resourceName The name of the file to be read.
>      * @return resource type of the last backed-up version of this resource.
>      * @throws CmsException Throws CmsException if operation was not succesful
>      * @author Sven Bonorden, GETIT GmbH
>      */
>     public int getResourceTypeForHist(String resourceName)
>         throws CmsException {
> 
>         int resourceType = -1;
>         ResultSet res =null;
>         PreparedStatement statement = null;
>         Connection con = null;
> 
>         try {
>             con = DriverManager.getConnection(m_poolNameBackup);
>             statement = con.prepareStatement(m_cq.get("C_RESOURCES_READ_ALL_BACKUP_ORDER_DESC"));
>             // read file header data from database
>             statement.setString(1, resourceName);
>             res = statement.executeQuery();
>             // read only the first row because this is the last version of the resource 
>             if(res.next()) {
>                 resourceType= res.getInt(m_cq.get("C_RESOURCES_RESOURCE_TYPE"));
>             }
>         } catch (SQLException e){
>             throw new CmsException("["+this.getClass().getName()+"] "+e.getMessage(),CmsException.C_SQL_ERROR, e);
>         } catch( Exception exc ) {
>             throw new CmsException("readResourceTypeForHist "+exc.getMessage(), CmsException.C_UNKNOWN_EXCEPTION, exc);
>         } finally {
>             // close all db-resources
>             if(res != null) {
>                 try {
>                     res.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(statement != null) {
>                 try {
>                     statement.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>             if(con != null) {
>                 try {
>                     con.close();
>                 } catch(SQLException exc) {
>                     // nothing to do here
>                 }
>             }
>         }
>         return resourceType;
>     }
> 
> com.opencms.file.genericSql.CmsResourceBroker:
> - new method:
>     /**
>      * Reads the resource type of a historic file in the OpenCms.<BR>
>      * No security checks.
>      * 
>      * @author Sven Bonorden, GETIT GmbH
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resourceName The name of the file to be read.
>      *
>      * @return resource type of the last backed-up version of this resource.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public int getResourceTypeForHist(CmsUser currentUser, CmsProject currentProject, String resourceName)
>         throws CmsException {
>         // no security check, accessRead cannot be used if the file was deleted.
> 
>         return(m_dbAccess.getResourceTypeForHist(resourceName));        
>     }
> 
> com.opencms.file.I_CmsResourceBroker:
> - new method:
>     /**
>      * Reads the resource type of a historic file in the OpenCms.<BR>
>      * No security checks.
>      * 
>      * @author Sven Bonorden, GETIT GmbH
>      *
>      * @param currentUser The user who requested this method.
>      * @param currentProject The current project of the user.
>      * @param resourceName The name of the file to be read.
>      *
>      * @return resource type of the last backed-up version of this resource.
>      *
>      * @throws CmsException Throws CmsException if operation was not succesful
>      */
>     public int getResourceTypeForHist(CmsUser currentUser, CmsProject currentProject, String resourceName)
>         throws CmsException;
> 
> com.opencms.file.CmsObject:
> - new method:
> /**
>  * Reads the resource type of a historic file in the OpenCms.<BR>
>  * No security checks as this method must also work if the file has been deleted.
>  * 
>  * @author Sven Bonorden, GETIT GmbH
>  *
>  * @param resourceName The name of the file to be read.
>  * @return resource type of the last backed-up version of this resource.
>  * @throws CmsException Throws CmsException if operation was not succesful
>  */
> public int getResourceTypeForHist(String resourceName) throws CmsException {
>     return (m_rb.getResourceTypeForHist(m_context.currentUser(), m_context.currentProject(), getSiteRoot(resourceName)));
> }
> 
> ---------------------------------------------------------------------------------------------------
> 
> We enhanced the folder tree popup to show not only the name, but also the title of the resource (if it is different from the name).
> This was necessary because our customer needed many folders named by internal ids and only the title showed readable information.
> As this change leads to slower performance, it must be checked if useful for other projects.
> 
> com.opencms.workplace.CmsFolderTree:
> - change method showTree:
> old version:
>                 template.setData(C_TREEENTRY, res.getName());
> 
> new version:
>                 String name = res.getName();
>                 String title = cms.readProperty(res.getAbsolutePath(), C_PROPERTY_TITLE);
>                 if (title != null && title.trim().length() > 0 && !title.equalsIgnoreCase(name)) {
>                     name = name + " (" + title + ")";
>                 }
>                 template.setData(C_TREEENTRY, name);
> 
> 
> ---------------------------------------------------------------------------------------------------
> 




More information about the opencms-dev mailing list