. Fixes/improvements for handling of author/creator in the repository and the web-client:

- added new aspect called "cm:author" with a single text property "cm:author"
 - fixed the content meta-data extractors to set the new cm:author property rather than the system cm:creator property (which was causing a couple of bugs spotted recently)
 - fixed the web-client to set the new cm:author property rather than the cm:creator property from user entered data into the UI
 - fixed web-client config of document properties screen to display cm:author
 - fixed client to not allow editing of the cm:creator value

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2034 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2005-12-13 15:25:56 +00:00
parent 6accb7a795
commit cafe3fb51f
12 changed files with 78 additions and 23 deletions

View File

@@ -264,6 +264,9 @@
<property name="contentService"> <property name="contentService">
<ref bean="contentService" /> <ref bean="contentService" />
</property> </property>
<property name="dictionaryService">
<ref bean="dictionaryService" />
</property>
<property name="metadataExtracterRegistry"> <property name="metadataExtracterRegistry">
<ref bean="metadataExtracterRegistry" /> <ref bean="metadataExtracterRegistry" />
</property> </property>

View File

@@ -71,6 +71,11 @@ cm_contentmodel.property.cm_modifier.description=Who last modified this item
cm_contentmodel.property.cm_accessed.title=Last Accessed Date cm_contentmodel.property.cm_accessed.title=Last Accessed Date
cm_contentmodel.property.cm_accessed.description=When this item was last accessed cm_contentmodel.property.cm_accessed.description=When this item was last accessed
cm_contentmodel.aspect.cm_author.title=Author
cm_contentmodel.aspect.cm_author.description=Author
cm_contentmodel.property.cm_author.title=Author
cm_contentmodel.property.cm_author.description=Author
cm_contentmodel.aspect.cm_localizable.title=Localizable cm_contentmodel.aspect.cm_localizable.title=Localizable
cm_contentmodel.aspect.cm_localizable.description=Localizable cm_contentmodel.aspect.cm_localizable.description=Localizable
cm_contentmodel.property.cm_locale.title=Locale cm_contentmodel.property.cm_locale.title=Locale

View File

@@ -218,7 +218,7 @@
<type>d:datetime</type> <type>d:datetime</type>
</property> </property>
<property name="cm:creator"> <property name="cm:creator">
<title>Author</title> <title>Creator</title>
<type>d:text</type> <type>d:text</type>
</property> </property>
<property name="cm:modified"> <property name="cm:modified">
@@ -309,7 +309,7 @@
<parent>cm:auditable</parent> <parent>cm:auditable</parent>
<!-- TODO: Support mandatory-aspects on an aspect in the meta-model <!-- TODO: Support mandatory-aspects on an aspect in the meta-model
<mandatory-aspects> <mandatory-aspects>
<aspect>Auditable</aspect> <aspect>cm:auditable</aspect>
</mandatory-aspects> </mandatory-aspects>
--> -->
<properties> <properties>
@@ -329,15 +329,20 @@
</property> </property>
</properties> </properties>
</aspect> </aspect>
<aspect name="cm:author">
<title>Author</title>
<properties>
<property name="cm:author">
<title>Author</title>
<type>d:text</type>
</property>
</properties>
</aspect>
<aspect name="cm:dublincore"> <aspect name="cm:dublincore">
<title>Dublin Core</title> <title>Dublin Core</title>
<parent>cm:titled</parent> <parent>cm:titled</parent>
<!-- TODO: Support mandatory-aspects on an aspect in the meta-model
<mandatory-aspects>
<aspect>Auditable</aspect>
</mandatory-aspects>
-->
<properties> <properties>
<property name="cm:publisher"> <property name="cm:publisher">
<title>Publisher</title> <title>Publisher</title>
@@ -372,13 +377,17 @@
<type>d:text</type> <type>d:text</type>
</property> </property>
</properties> </properties>
<mandatory-aspects>
<aspect>cm:auditable</aspect>
<aspect>cm:author</aspect>
</mandatory-aspects>
</aspect> </aspect>
<!-- <!--
<aspect name="cm:subjectable"> <aspect name="cm:subjectable">
<title>Subjectable</title> <title>Subjectable</title>
<mandatory-aspects> <mandatory-aspects>
<aspect>Auditable</aspect> <aspect>cm:auditable</aspect>
</mandatory-aspects> </mandatory-aspects>
<properties> <properties>
<property name="cm:subject"> <property name="cm:subject">

View File

@@ -83,6 +83,10 @@ public interface ContentModel
static final QName PROP_MODIFIER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "modifier"); static final QName PROP_MODIFIER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "modifier");
static final QName PROP_ACCESSED = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "accessed"); static final QName PROP_ACCESSED = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "accessed");
// author aspect
static final QName ASPECT_AUTHOR = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "author");
static final QName PROP_AUTHOR = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "author");
// categories // categories
static final QName TYPE_CATEGORYROOT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "category_root"); static final QName TYPE_CATEGORYROOT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "category_root");
static final QName ASPECT_CLASSIFIABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "classifiable"); static final QName ASPECT_CLASSIFIABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "classifiable");

View File

@@ -26,6 +26,9 @@ import org.alfresco.repo.content.metadata.MetadataExtracter;
import org.alfresco.repo.content.metadata.MetadataExtracterRegistry; import org.alfresco.repo.content.metadata.MetadataExtracterRegistry;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -96,6 +99,19 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
{ {
this.contentService = contentService; this.contentService = contentService;
} }
/**
* The dictionary service
*/
private DictionaryService dictionaryService;
/**
* @param dictService The DictionaryService to set.
*/
public void setDictionaryService(DictionaryService dictService)
{
this.dictionaryService = dictService;
}
/** /**
* Our Extracter * Our Extracter
@@ -140,10 +156,29 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
boolean changed = false; boolean changed = false;
for (QName key : newProps.keySet()) for (QName key : newProps.keySet())
{ {
// check if we need to add an aspect for the prop
ClassDefinition propClass = dictionaryService.getProperty(key).getContainerClass();
if (propClass.isAspect() &&
nodeService.hasAspect(actionedUponNodeRef, propClass.getName()) == false)
{
Map<QName, Serializable> aspectProps = new HashMap<QName, Serializable>(3, 1.0f);
for (QName defKey : propClass.getProperties().keySet())
{
if (dictionaryService.getProperty(defKey).isMandatory())
{
aspectProps.put(defKey, allProps.get(defKey));
allProps.remove(defKey);
}
}
nodeService.addAspect(actionedUponNodeRef, propClass.getName(), aspectProps);
}
Serializable value = newProps.get(key); Serializable value = newProps.get(key);
if (value == null) if (value == null)
{
continue; // Content extracters shouldn't do this continue; // Content extracters shouldn't do this
}
// Look up the old value, and check for nulls // Look up the old value, and check for nulls
Serializable oldValue = allProps.get(key); Serializable oldValue = allProps.get(key);
if (oldValue == null || oldValue.toString().length() == 0) if (oldValue == null || oldValue.toString().length() == 0)
@@ -152,11 +187,11 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
changed = true; changed = true;
} }
} }
// TODO: Should we be adding the associated aspects or is
// that done by the type system
// (or are ad-hoc properties allowed?)
if (changed) if (changed)
{
nodeService.setProperties(actionedUponNodeRef, allProps); nodeService.setProperties(actionedUponNodeRef, allProps);
}
} }
} }
} }

View File

@@ -116,7 +116,7 @@ public class HtmlMetadataExtracter extends AbstractMetadataExtracter
if (name.equalsIgnoreCase("creator") || name.equalsIgnoreCase("author") if (name.equalsIgnoreCase("creator") || name.equalsIgnoreCase("author")
|| name.equalsIgnoreCase("dc.creator")) || name.equalsIgnoreCase("dc.creator"))
{ {
trimPut(ContentModel.PROP_CREATOR, valueO, tempDestination); trimPut(ContentModel.PROP_AUTHOR, valueO, tempDestination);
} }
if (name.equalsIgnoreCase("description") || name.equalsIgnoreCase("dc.description")) if (name.equalsIgnoreCase("description") || name.equalsIgnoreCase("dc.description"))
{ {

View File

@@ -138,7 +138,7 @@ public class MP3MetadataExtracter extends AbstractMetadataExtracter
} }
if (props.get(PROP_ARTIST) != null) if (props.get(PROP_ARTIST) != null)
{ {
destination.put(ContentModel.PROP_CREATOR, props.get(PROP_ARTIST)); destination.put(ContentModel.PROP_AUTHOR, props.get(PROP_ARTIST));
} }
String description = getDescription(props); String description = getDescription(props);
if (description != null) if (description != null)

View File

@@ -71,9 +71,8 @@ public class OfficeMetadataExtracter extends AbstractMetadataExtracter
// Auditable aspect // Auditable aspect
trimPut(ContentModel.PROP_CREATED, si.getCreateDateTime(), destination); trimPut(ContentModel.PROP_CREATED, si.getCreateDateTime(), destination);
trimPut(ContentModel.PROP_CREATOR, si.getAuthor(), destination); trimPut(ContentModel.PROP_MODIFIED, si.getLastSaveDateTime(), destination);
trimPut(ContentModel.PROP_MODIFIED, si.getLastSaveDateTime(), destination); trimPut(ContentModel.PROP_AUTHOR, si.getAuthor(), destination);
trimPut(ContentModel.PROP_MODIFIER, si.getLastAuthor(), destination);
} }
else if (ps instanceof DocumentSummaryInformation) else if (ps instanceof DocumentSummaryInformation)
{ {

View File

@@ -78,7 +78,7 @@ public class OpenDocumentMetadataExtracter extends AbstractMetadataExtracter
if (docInfo != null) if (docInfo != null)
{ {
// set the metadata // set the metadata
destination.put(ContentModel.PROP_CREATOR, docInfo.getCreator()); destination.put(ContentModel.PROP_AUTHOR, docInfo.getCreator());
destination.put(ContentModel.PROP_TITLE, docInfo.getTitle()); destination.put(ContentModel.PROP_TITLE, docInfo.getTitle());
destination.put(ContentModel.PROP_DESCRIPTION, docInfo.getDescription()); destination.put(ContentModel.PROP_DESCRIPTION, docInfo.getDescription());
destination.put(ContentModel.PROP_CREATED, docInfo.getCreationDate()); destination.put(ContentModel.PROP_CREATED, docInfo.getCreationDate());

View File

@@ -60,7 +60,7 @@ public class PdfBoxMetadataExtracter extends AbstractMetadataExtracter
// Scoop out the metadata // Scoop out the metadata
PDDocumentInformation docInfo = pdf.getDocumentInformation(); PDDocumentInformation docInfo = pdf.getDocumentInformation();
trimPut(ContentModel.PROP_CREATOR, docInfo.getAuthor(), destination); trimPut(ContentModel.PROP_AUTHOR, docInfo.getAuthor(), destination);
trimPut(ContentModel.PROP_TITLE, docInfo.getTitle(), destination); trimPut(ContentModel.PROP_TITLE, docInfo.getTitle(), destination);
trimPut(ContentModel.PROP_DESCRIPTION, docInfo.getSubject(), destination); trimPut(ContentModel.PROP_DESCRIPTION, docInfo.getSubject(), destination);

View File

@@ -146,7 +146,7 @@ public class UnoMetadataExtracter extends AbstractMetadataExtracter
// Auditable aspect // Auditable aspect
// trimPut(ContentModel.PROP_CREATED, // trimPut(ContentModel.PROP_CREATED,
// si.getCreateDateTime(), destination); // si.getCreateDateTime(), destination);
trimPut(ContentModel.PROP_CREATOR, propSet.getPropertyValue("Author"), destination); trimPut(ContentModel.PROP_AUTHOR, propSet.getPropertyValue("Author"), destination);
// trimPut(ContentModel.PROP_MODIFIED, // trimPut(ContentModel.PROP_MODIFIED,
// si.getLastSaveDateTime(), destination); // si.getLastSaveDateTime(), destination);
// trimPut(ContentModel.PROP_MODIFIER, si.getLastAuthor(), // trimPut(ContentModel.PROP_MODIFIER, si.getLastAuthor(),

View File

@@ -73,7 +73,7 @@ public class QNameMap<K,V> implements Map, Cloneable
*/ */
public boolean containsKey(Object key) public boolean containsKey(Object key)
{ {
return (this.contents.containsKey(QName.resolveToQNameString(resolver, (String)key))); return (this.contents.containsKey(QName.resolveToQNameString(resolver, key.toString())));
} }
/** /**
@@ -100,7 +100,7 @@ public class QNameMap<K,V> implements Map, Cloneable
*/ */
public Object put(Object key, Object value) public Object put(Object key, Object value)
{ {
return this.contents.put(QName.resolveToQNameString(resolver, (String)key), value); return this.contents.put(QName.resolveToQNameString(resolver, key.toString()), value);
} }
/** /**
@@ -108,7 +108,7 @@ public class QNameMap<K,V> implements Map, Cloneable
*/ */
public Object remove(Object key) public Object remove(Object key)
{ {
return this.contents.remove(QName.resolveToQNameString(resolver, (String)key)); return this.contents.remove(QName.resolveToQNameString(resolver, key.toString()));
} }
/** /**