Skip to content

Commit

Permalink
Fixed problem with link handling for detail contents in HTML fields.
Browse files Browse the repository at this point in the history
  • Loading branch information
gWestenberger committed Jan 24, 2014
1 parent 0c88fa7 commit f4ea49f
Show file tree
Hide file tree
Showing 12 changed files with 690 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ ERR_CREATE_SIBLING_1 =Fehler beim Erstellen einer Ver
ERR_CREATE_TEMPFILE_PROJECT_0 =Fehler beim Erstellen eines Projekts für temporäre Workplace Dateien.
ERR_CREATE_USER_1 =Fehler beim Hinzufügen des Benutzers "{0}".
ERR_DB_OPERATION_0 =Fehler beim Datenbankzugriff.
ERR_DB_OPERATION_1 =Fehler beim Datenbankzugriff: {0}
ERR_DELETE_HISTORY_4 =Fehler beim Löschen der Backupversion für {0} zurückgelassen werden maximal {1} Versionen ({2} Versionen für gelöschte Ressourcen, nicht älter als {3, date} um {3, time}).
ERR_DELETE_GROUP_1 =Fehler beim Löschen der Gruppe "{0}".
ERR_DELETE_ORGUNIT_1 =Fehler beim Löschen der organisatorischen Einheit "{0}".
Expand Down
26 changes: 25 additions & 1 deletion src/org/opencms/ade/configuration/CmsADEManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ protected enum Status {

/** The name of the sitemap configuration file type. */
public static final String CONFIG_FOLDER_TYPE = "content_folder";

/** The path for sitemap configuration files relative from the base path. */
public static final String CONFIG_SUFFIX = "/"
+ CmsADEManager.CONTENT_FOLDER_NAME
Expand Down Expand Up @@ -201,6 +200,9 @@ protected enum Status {
/** The offline inherited container configuration cache. */
private CmsContainerConfigurationCache m_offlineContainerConfigurationCache;

/** The detail id cache for the Offline project. */
private CmsDetailNameCache m_offlineDetailIdCache;

/** The offline formatter bean cache. */
private CmsFormatterConfigurationCache m_offlineFormatterCache;

Expand All @@ -213,6 +215,9 @@ protected enum Status {
/** The online inherited container configuration cache. */
private CmsContainerConfigurationCache m_onlineContainerConfigurationCache;

/** The Online project detail id cache. */
private CmsDetailNameCache m_onlineDetailIdCache;

/** The online formatter bean cache. */
private CmsFormatterConfigurationCache m_onlineFormatterCache;

Expand Down Expand Up @@ -324,6 +329,18 @@ public CmsContainerElementBean getCurrentElement(ServletRequest req) throws CmsE
return element;
}

/**
* Gets the detail id cache for the Online or Offline projects.<p>
*
* @param online if true, gets the Online project detail id
*
* @return the detail name cache
*/
public CmsDetailNameCache getDetailIdCache(boolean online) {

return online ? m_onlineDetailIdCache : m_offlineDetailIdCache;
}

/**
* Gets the detail page for a content element.<p>
*
Expand Down Expand Up @@ -712,6 +729,12 @@ public synchronized void initialize() {
m_onlineFormatterCache = new CmsFormatterConfigurationCache(m_onlineCms, "online formatters");
m_offlineFormatterCache.reload();
m_onlineFormatterCache.reload();

m_offlineDetailIdCache = new CmsDetailNameCache(m_offlineCms);
m_onlineDetailIdCache = new CmsDetailNameCache(m_onlineCms);
m_offlineDetailIdCache.initialize();
m_onlineDetailIdCache.initialize();

CmsGlobalConfigurationCacheEventHandler handler = new CmsGlobalConfigurationCacheEventHandler(
m_onlineCms);
handler.addCache(m_offlineCache, m_onlineCache, "ADE configuration cache");
Expand All @@ -720,6 +743,7 @@ public synchronized void initialize() {
m_onlineContainerConfigurationCache,
"Inherited container cache");
handler.addCache(m_offlineFormatterCache, m_onlineFormatterCache, "formatter configuration cache");
handler.addCache(m_offlineDetailIdCache, m_onlineDetailIdCache, "Detail ID cache");
OpenCms.getEventManager().addCmsEventListener(handler);
m_initStatus = Status.initialized;
} catch (CmsException e) {
Expand Down
247 changes: 247 additions & 0 deletions src/org/opencms/ade/configuration/CmsDetailNameCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

package org.opencms.ade.configuration;

import org.opencms.db.CmsPublishedResource;
import org.opencms.db.urlname.CmsUrlNameMappingEntry;
import org.opencms.db.urlname.CmsUrlNameMappingFilter;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
import org.opencms.file.types.CmsResourceTypeXmlContent;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.loader.CmsLoaderException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsManyToOneMap;
import org.opencms.util.CmsUUID;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;

import com.google.common.collect.Sets;

/**
* A cache which stores structure ids for URL names.<p>
*/
public class CmsDetailNameCache implements I_CmsGlobalConfigurationCache {

/** The delay between updates. */
public static final int DELAY_MILLIS = 10000;

/** The logger for this class. */
private static final Log LOG = CmsLog.getLog(CmsDetailNameCache.class);

/** The CMS context used by this cache. */
private CmsObject m_cms;

/** The internal map from URL names to structure ids. */
private CmsManyToOneMap<String, CmsUUID> m_detailIdCache = new CmsManyToOneMap<String, CmsUUID>();

/** The set of structure ids for which the URL names have to be updated. */
private Set<CmsUUID> m_updateSet = Sets.newHashSet();

/**
* Creates a new instance.<p>
*
* @param cms the CMS context to use
*/
public CmsDetailNameCache(CmsObject cms) {

m_cms = cms;
}

/**
* @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#clear()
*/
public void clear() {

markForUpdate(CmsUUID.getNullUUID());

}

/**
* Gets the structure id for a given URL name.<p>
*
* @param name the URL name
* @return the structure id for the URL name
*/
public CmsUUID getDetailId(String name) {

return m_detailIdCache.get(name);
}

/**
* Initializes the cache by scheduling the update actions and loading the initial cache contents.<p>
*/
public void initialize() {

OpenCms.getExecutor().scheduleWithFixedDelay(new Runnable() {

public void run() {

checkForUpdates();
}
}, DELAY_MILLIS, DELAY_MILLIS, TimeUnit.MILLISECONDS);
reload();
}

/**
* @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#remove(org.opencms.db.CmsPublishedResource)
*/
public void remove(CmsPublishedResource pubRes) {

checkIfUpdateIsNeeded(pubRes.getStructureId(), pubRes.getRootPath(), pubRes.getType());
}

/**
* @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#remove(org.opencms.file.CmsResource)
*/
public void remove(CmsResource resource) {

checkIfUpdateIsNeeded(resource.getStructureId(), resource.getRootPath(), resource.getTypeId());

}

/**
* @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#update(org.opencms.db.CmsPublishedResource)
*/
public void update(CmsPublishedResource pubRes) {

checkIfUpdateIsNeeded(pubRes.getStructureId(), pubRes.getRootPath(), pubRes.getType());

}

/**
* @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#update(org.opencms.file.CmsResource)
*/
public void update(CmsResource resource) {

checkIfUpdateIsNeeded(resource.getStructureId(), resource.getRootPath(), resource.getTypeId());

}

/**
* Checks if any updates are necessary and if so, performs them.<p>
*/
synchronized void checkForUpdates() {

if (!m_updateSet.isEmpty()) {
Set<CmsUUID> copiedIds = Sets.newHashSet(m_updateSet);
m_updateSet.clear();

if (copiedIds.contains(CmsUUID.getNullUUID())) {
LOG.info("Updating detail name cache: reloading...");
reload();
} else {
LOG.info("Updating detail name cache. Number of changed files: " + copiedIds.size());
CmsManyToOneMap<String, CmsUUID> cacheCopy = new CmsManyToOneMap<String, CmsUUID>(m_detailIdCache);
for (CmsUUID id : copiedIds) {
Set<String> urlNames = getUrlNames(id);
cacheCopy.removeValue(id);
for (String urlName : urlNames) {
cacheCopy.put(urlName, id);
}
}
m_detailIdCache = cacheCopy;
}
}
}

/**
* Checks if the cache needs to be updated for the resource, and if so, marks the structure id for updating.<p>
*
* @param structureId the structure id for the resource
* @param rootPath the path of the resource
* @param typeId the resource type id
*/
private void checkIfUpdateIsNeeded(CmsUUID structureId, String rootPath, int typeId) {

try {
I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(typeId);
if ((resType instanceof CmsResourceTypeXmlContent)
&& !OpenCms.getResourceManager().matchResourceType(
CmsResourceTypeXmlContainerPage.RESOURCE_TYPE_NAME,
typeId)) {
markForUpdate(structureId);
}
} catch (CmsLoaderException e) {
// resource type not found, just log an error
LOG.error(e.getLocalizedMessage(), e);
}
}

/**
* Reads the URL names for the id.<p>
*
* @param id the structure id of a resource
* @return the URL names for the resource
*/
private Set<String> getUrlNames(CmsUUID id) {

try {
return new HashSet<String>(m_cms.readUrlNamesForAllLocales(id));
} catch (Exception e) {
LOG.error(e.getLocalizedMessage(), e);
return Collections.emptySet();
}
}

/**
* Marks the structure id for updating.<p>
*
* @param id the structure id to update
*/
private synchronized void markForUpdate(CmsUUID id) {

m_updateSet.add(id);
}

/**
* Loads the complete URL name data into the cache.<p>
*/
private void reload() {

CmsManyToOneMap<String, CmsUUID> newMap = new CmsManyToOneMap<String, CmsUUID>();
try {
List<CmsUrlNameMappingEntry> mappings = m_cms.readUrlNameMappings(CmsUrlNameMappingFilter.ALL);
LOG.info("Initializing detail name cache with " + mappings.size() + " entries");
for (CmsUrlNameMappingEntry entry : mappings) {
newMap.put(entry.getName(), entry.getStructureId());
}
m_detailIdCache = newMap;
} catch (Exception e) {
LOG.error(e.getLocalizedMessage(), e);
}
}
}
19 changes: 19 additions & 0 deletions src/org/opencms/db/CmsDriverManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7847,6 +7847,25 @@ public List<CmsUrlNameMappingEntry> readUrlNameMappingEntries(
return vfsDriver.readUrlNameMappingEntries(dbc, online, filter);
}

/**
* Reads the URL name mappings matching the given filter.<p>
*
* @param dbc the DB context to use
* @param filter the filter used to select the mapping entries
* @return the entries matching the given filter
*
* @throws CmsDataAccessException if something goes wrong
*/
public List<CmsUrlNameMappingEntry> readUrlNameMappings(CmsDbContext dbc, CmsUrlNameMappingFilter filter)
throws CmsDataAccessException {

List<CmsUrlNameMappingEntry> entries = getVfsDriver(dbc).readUrlNameMappingEntries(
dbc,
dbc.currentProject().isOnlineProject(),
filter);
return entries;
}

/**
* Reads the newest URL names of a resource for all locales.<p>
*
Expand Down
25 changes: 25 additions & 0 deletions src/org/opencms/db/CmsSecurityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -5226,6 +5226,31 @@ public List<CmsResource> readSubscribedResources(
return result;
}

/**
* Reads the URL name mappings matching a given filter.<p>
*
* @param context the current request context
* @param filter the filter to match
*
* @return the matching URL name mappings
*
* @throws CmsException if something goes wrong
*/
public List<CmsUrlNameMappingEntry> readUrlNameMappings(CmsRequestContext context, CmsUrlNameMappingFilter filter)
throws CmsException {

CmsDbContext dbc = m_dbContextFactory.getDbContext(context);
try {
return m_driverManager.readUrlNameMappings(dbc, filter);
} catch (Exception e) {
CmsMessageContainer message = Messages.get().container(Messages.ERR_DB_OPERATION_1, e.getLocalizedMessage());
dbc.report(null, message, e);
return null; // will never be reached
} finally {
dbc.clear();
}
}

/**
* Reads the newest URL names of a structure id for all locales.<p>
*
Expand Down
3 changes: 3 additions & 0 deletions src/org/opencms/db/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ public final class Messages extends A_CmsMessageBundle {
/** Message constant for key in the resource bundle. */
public static final String ERR_DB_OPERATION_0 = "ERR_DB_OPERATION_0";

/** Message constant for key in the resource bundle. */
public static final String ERR_DB_OPERATION_1 = "ERR_DB_OPERATION_1";

/** Message constant for key in the resource bundle. */
public static final String ERR_DELETE_GROUP_1 = "ERR_DELETE_GROUP_1";

Expand Down
1 change: 1 addition & 0 deletions src/org/opencms/db/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ ERR_CREATE_SIBLING_1 =Error creating a sibling of "{0
ERR_CREATE_TEMPFILE_PROJECT_0 =Error creating project for temporary workplace files.
ERR_CREATE_USER_1 =Error adding the user "{0}".
ERR_DB_OPERATION_0 =Error in database operation.
ERR_DB_OPERATION_1 =Error in database operation: {0}
ERR_DELETE_HISTORY_4 =Error deleting the historical versions for {0} leaving at most {1} versions ({2} versions of deleted resources not older than {3,date} at {3,time}).
ERR_DELETE_GROUP_1 =Error deleting the group "{0}".
ERR_DELETE_LOG_0 =Error deleting log entries.
Expand Down
Loading

0 comments on commit f4ea49f

Please sign in to comment.