Migration Notes
Why To Migrate?
Here are the key reasons to use the new API provided by GroupDocs.Metadata for Java starting from version 20.2:
- The* Metadata* class is introduced as a **single entry point** to manage metadata in files of all supported formats.
- Extracting and updating metadata was unified for all supported formats.
- The product architecture was redesigned from scratch in order to simplify most common operations with metadata properties.
- Getting document information and preview generation procedures were simplified.
How To Migrate?
Here is a brief comparison of how to manage metadata using the old and new API.
Loading Files
Any Supported Format
The following examples show how to load a file of any supported format.
Old API
try (FormatBase format = FormatFactory.recognizeFormat("D:\\input.doc")) {
// ...
}
New API
try (Metadata metadata = new Metadata("D:\\input.doc")) {
// ...
}
Some Specific Format
The code samples below demonstrate how to load a file of a specific format.
Old API
try (XlsFormat xlsFormat = new XlsFormat("D:\\input.xls")) {
// ...
}
New API
LoadOptions loadOptions = new LoadOptions(FileFormat.Spreadsheet);
try (Metadata metadata = new Metadata(Constants.InputXls, loadOptions)) {
SpreadsheetRootPackage root = metadata.getRootPackageGeneric();
// ...
}
Working with Metadata using Regular Expressions
Finding Metadata using Regular Expressions
The following code snippets retrieve metadata from a file using a regular expression.
Old API
Pattern pattern = Pattern.compile("author|company", Pattern.CASE_INSENSITIVE);
MetadataPropertyCollection properties = SearchFacade.scanDocument("D:\\input.docx", pattern);
for (int i = 0; i < properties.getCount(); i++)
{
System.out.println(properties.readByIndex(i));
}
New API
public class FindPropertiesByRegex {
public static void run() {
Pattern pattern = Pattern.compile("author|company", Pattern.CASE_INSENSITIVE);
try (Metadata metadata = new Metadata(Constants.InputDocx)) {
// This method searches for properties across all metadata packages and works with all supported formats
IReadOnlyList<MetadataProperty> properties = metadata.findProperties(new FindPropertiesByRegex().new RegexSpecification(pattern));
for (MetadataProperty property : properties) {
System.out.println(String.format("%s = %s", property.getName(), property.getValue()));
}
}
}
public class RegexSpecification extends Specification {
private Pattern pattern;
public RegexSpecification(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean isSatisfiedBy(MetadataProperty metadataProperty) {
Matcher matcher = pattern.matcher(metadataProperty.getName());
return matcher.find();
}
}
}
Replacing Metadata using Regular Expressions
The following code snippets show how to replace metadata properties using a regular expression.
Old API
Pattern pattern = Pattern.compile("^author|company$", Pattern.CASE_INSENSITIVE);
String replaceValue = "Aspose";
SearchFacade.replaceInDocument("D:\\input.docx", pattern, replaceValue, "D:\\output.docx");
New API
public class UpdatePropertiesByRegex {
public static void run() {
Pattern pattern = Pattern.compile("^author|company$", Pattern.CASE_INSENSITIVE);
PropertyValue replaceValue = new PropertyValue("Aspose");
try (Metadata metadata = new Metadata(Constants.InputDocx)) {
// This method updates writable properties across all metadata packages and works with all supported formats
metadata.updateProperties(new UpdatePropertiesByRegex().new RegexSpecification(pattern), replaceValue);
metadata.save(Constants.OutputDocx);
}
}
private class RegexSpecification extends Specification {
private Pattern pattern;
public RegexSpecification(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean isSatisfiedBy(MetadataProperty metadataProperty) {
Matcher matcher = pattern.matcher(metadataProperty.getName());
return matcher.find();
}
}
}
Exporting Metadata
Export Metadata Properties to CSV
The following code snippets show how to export metadata properties to a CSV file.
Old API
try (FileOutputStream stream = new FileOutputStream("D:\\metadata.csv")) {
byte[] content = ExportFacade.exportToCsv("D:\\input.eml");
stream.write(content);
}
New API
try (Metadata metadata = new Metadata(Constants.InputEml)) {
// We use a predicate that extracts all metadata properties
IReadOnlyList<MetadataProperty> properties = metadata.findProperties(new AnySpecification());
String delimiter = ";";
StringBuilder builder = new StringBuilder();
builder.append(String.format("Name%sValue", delimiter));
builder.append("\n");
for (MetadataProperty property : properties) {
builder.append(String.format("\"%s\"%s\"%s\"", property.getName(), delimiter, formatValue(property.getValue())));
builder.append("\n");
}
try (PrintWriter out = new PrintWriter(Constants.OutputCsv)) {
out.println(builder.toString());
}
}
Using the Replace API
Update Values with IReplaceHandler
The code samples below show how to update metadata properties using a custom filter.
Old API (Implementation of IReplaceHandler)
public class AuthorReplaceHandler implements IReplaceHandler<MetadataProperty>
{
public AuthorReplaceHandler(String outputPath)
{
this.outputPath = outputPath;
}
public String outputPath;
@Override
public String getOutputPath() {
return outputPath;
}
public boolean handle(MetadataProperty property)
{
// if property name is 'author'
if ("author".equalsIgnoreCase(property.getName()))
{
// update property value
property.setValue(new PropertyValue("Jack London"));
// and mark property as updated
return true;
}
// ignore all other properties
return false;
}
}
Old API (Usage of AuthorReplaceHandler)
// initialize custom handler, send output path using constructor
IReplaceHandler<MetadataProperty> replaceHandler = new AuthorReplaceHandler("D:\\output.docx");
// replace author
int affectedPropertiesCount = SearchFacade.replaceInDocument("D:\\intput.docx", replaceHandler);
In the new API there is no need to use the IReplaceHandler interface since you have full control over property filters using the GrooupDocs.Metadata search engine.
New API
public class UpdatePropertyValue {
public static void run() {
try (Metadata metadata = new Metadata(Constants.InputDocx)) {
int affected = metadata.updateProperties(new UpdatePropertyValue().new CustomNameComparerSpecification("author"), new PropertyValue("Jack London"));
System.out.println(affected);
metadata.save(Constants.OutputDocx);
}
}
private class CustomNameComparerSpecification extends Specification {
private String name;
public CustomNameComparerSpecification(String name) {
this.name = name;
}
@Override
public boolean isSatisfiedBy(MetadataProperty metadataProperty) {
return metadataProperty.getName().equalsIgnoreCase(name);
}
}
}
Extracting a Specific Metadata Package
Extract a Metadata Package of a Specific Type
The code samples below demonstrate how to fetch a metadata package with a specific type.
Old API
DublinCoreMetadata dublinCoreMetadata = (DublinCoreMetadata) MetadataUtility.extractSpecificMetadata("D:\\input.docx", MetadataType.DublinCore);
if (dublinCoreMetadata != null)
{
System.out.println(dublinCoreMetadata.getCreator());
System.out.println(dublinCoreMetadata.getFormat());
System.out.println(dublinCoreMetadata.getSubject());
}
New API
public class ExtractPackageUsingCommonApi {
public static void run() {
try (Metadata metadata = new Metadata(Constants.InputDocx)) {
IReadOnlyList<MetadataProperty> properties = metadata.findProperties(new ExtractPackageUsingCommonApi().new AssignableFromSpecification(DublinCorePackage.class));
MetadataProperty property = properties.getCount() > 0 ? properties.get_Item(0) : null;
if (property != null) {
DublinCorePackage dcPackage = property.getValue().toClass(DublinCorePackage.class);
System.out.println(dcPackage.getFormat());
System.out.println(dcPackage.getContributor());
System.out.println(dcPackage.getCoverage());
System.out.println(dcPackage.getCreator());
System.out.println(dcPackage.getSource());
System.out.println(dcPackage.getDescription());
// ...
}
}
}
private class AssignableFromSpecification extends Specification {
private Class<?> clazz;
public AssignableFromSpecification(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public boolean isSatisfiedBy(MetadataProperty metadataProperty) {
return metadataProperty.getValue().getRawValue() != null && clazz.isAssignableFrom(metadataProperty.getValue().getRawValue().getClass());
}
}
}