diff options
author | Eike Stepper | 2018-04-24 08:24:49 +0000 |
---|---|---|
committer | Eike Stepper | 2018-04-24 08:24:49 +0000 |
commit | 3b9bf918e6e6029c6165bead0c4222dd6ff13fea (patch) | |
tree | 2c48282ed80114ca1061b3240caa159a73dfab9e /plugins | |
parent | 8d9891fd33bda115e575d274a04cf32746f3debc (diff) | |
download | cdo-3b9bf918e6e6029c6165bead0c4222dd6ff13fea.tar.gz cdo-3b9bf918e6e6029c6165bead0c4222dd6ff13fea.tar.xz cdo-3b9bf918e6e6029c6165bead0c4222dd6ff13fea.zip |
[430528] CDO Server Exporter doesn't handle DetachedRevisions
https://bugs.eclipse.org/bugs/show_bug.cgi?id=430528
Diffstat (limited to 'plugins')
8 files changed, 173 insertions, 59 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java index 0889252f14..205e74fcea 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java @@ -40,6 +40,12 @@ public class DetachedCDORevision extends SyntheticCDORevision public DetachedCDORevision(EClass eClass, CDOID id, CDOBranch branch, int version, long timeStamp, long revised) { super(eClass, id, branch); + + if (version < 0) + { + throw new IllegalArgumentException("Version is negative: " + version); + } + this.version = version; this.timeStamp = timeStamp; this.revised = revised; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java index f885e7a5d4..b342745cdb 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java @@ -332,13 +332,14 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I } } - private void initSQLStrings() + protected void initSQLStrings() { // ----------- Select all revisions (for handleRevisions) --- StringBuilder builder = new StringBuilder("SELECT "); //$NON-NLS-1$ builder.append(ATTRIBUTES_ID); builder.append(", "); //$NON-NLS-1$ builder.append(ATTRIBUTES_VERSION); + appendSelectForHandleFields(builder); builder.append(" FROM "); //$NON-NLS-1$ builder.append(table); sqlSelectForHandle = builder.toString(); @@ -352,6 +353,21 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I sqlSelectForChangeSet = builder.toString(); } + protected void appendSelectForHandleFields(StringBuilder builder) + { + // Do nothing. + } + + protected String getSQLSelectForHandle() + { + return sqlSelectForHandle; + } + + protected String getSQLSelectForChangeSet() + { + return sqlSelectForChangeSet; + } + protected IDBField addContainerField(IDBTable table, DBType idType, int idLength) { return table.addField(ATTRIBUTES_CONTAINER, idType, idLength, true); @@ -697,6 +713,7 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I IRepository repository = accessor.getStore().getRepository(); CDORevisionManager revisionManager = repository.getRevisionManager(); CDOBranchManager branchManager = repository.getBranchManager(); + CDOBranch mainBranch = branchManager.getMainBranch(); // TODO: test for timeStamp == INVALID_TIME and encode revision.isValid() as WHERE instead of fetching all revisions // in order to increase performance @@ -757,8 +774,8 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I if (version >= CDOBranchVersion.FIRST_VERSION) { - InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchManager.getMainBranch().getVersion(version), - CDORevision.UNCHUNKED, true); + CDOBranchVersion branchVersion = mainBranch.getVersion(version); + InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion, CDORevision.UNCHUNKED, true); if (!handler.handleRevision(revision)) { @@ -767,8 +784,12 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I } else { + EClass eClass = getEClass(); + long created = resultSet.getLong(3); + long revised = resultSet.getLong(4); + // Tell handler about detached IDs - InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0); + InternalCDORevision revision = new DetachedCDORevision(eClass, id, mainBranch, -version, created, revised); if (!handler.handleRevision(revision)) { break; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java index 8859f45065..6feb25ebd9 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java @@ -105,8 +105,11 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping initSQLStrings(); } - private void initSQLStrings() + @Override + protected void initSQLStrings() { + super.initSQLStrings(); + // ----------- Select Revision --------------------------- String[] strings = buildSQLSelects(false); String sqlSelectAttributesPrefix = strings[0]; @@ -187,6 +190,15 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping sqlRawDeleteAttributes = builder.toString(); } + @Override + protected void appendSelectForHandleFields(StringBuilder builder) + { + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + } + private String[] buildSQLSelects(boolean forUnits) { String[] strings = new String[3]; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java index d4d1d36aef..dabbffafa3 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java @@ -87,10 +87,6 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp private String sqlReviseAttributes; - private String sqlSelectForHandle; - - private String sqlSelectForChangeSet; - private String sqlRawDeleteAttributes; public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) @@ -105,8 +101,11 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp return table.addField(ATTRIBUTES_BRANCH, DBType.INTEGER, true); } - private void initSQLStrings() + @Override + protected void initSQLStrings() { + super.initSQLStrings(); + // ----------- Select Revision --------------------------- StringBuilder builder = new StringBuilder(); builder.append("SELECT "); //$NON-NLS-1$ @@ -205,25 +204,6 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp builder.append("=0"); //$NON-NLS-1$ sqlSelectAllObjectIDs = builder.toString(); - // ----------- Select all revisions (for handleRevision) --- - builder = new StringBuilder("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - sqlSelectForHandle = builder.toString(); - - // ----------- Select all revisions (for handleRevision) --- - builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - sqlSelectForChangeSet = builder.toString(); - // ----------- Raw delete one specific revision ------ builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ builder.append(getTable()); @@ -237,6 +217,17 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp sqlRawDeleteAttributes = builder.toString(); } + @Override + protected void appendSelectForHandleFields(StringBuilder builder) + { + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + } + public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { long timeStamp = revision.getTimeStamp(); @@ -684,7 +675,7 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp @Override public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime, CDORevisionHandler handler) { - StringBuilder builder = new StringBuilder(sqlSelectForHandle); + StringBuilder builder = new StringBuilder(getSQLSelectForHandle()); boolean whereAppend = false; if (branch != null) @@ -757,11 +748,11 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp { CDOID id = idHandler.getCDOID(resultSet, 1); int version = resultSet.getInt(2); + CDOBranch revisionBranch = branchManager.getBranch(resultSet.getInt(3)); if (version >= CDOBranchVersion.FIRST_VERSION) { - int branchID = resultSet.getInt(3); - CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version)); + CDOBranchVersion branchVersion = revisionBranch.getVersion(version); InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion, CDORevision.UNCHUNKED, true); if (!handler.handleRevision(revision)) @@ -771,13 +762,16 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp } else { + EClass eClass = getEClass(); + long created = resultSet.getLong(4); + long revised = resultSet.getLong(5); + // Tell handler about detached IDs - InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0); + InternalCDORevision revision = new DetachedCDORevision(eClass, id, revisionBranch, -version, created, revised); if (!handler.handleRevision(revision)) { break; } - } } } @@ -795,7 +789,7 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp @Override public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments) { - StringBuilder builder = new StringBuilder(sqlSelectForChangeSet); + StringBuilder builder = new StringBuilder(getSQLSelectForChangeSet()); boolean isFirst = true; for (int i = 0; i < segments.length; i++) diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java index be80e65c78..b0946c36e4 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java @@ -89,8 +89,11 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi hasLists = !getListMappings().isEmpty(); } - private void initSQLStrings() + @Override + protected void initSQLStrings() { + super.initSQLStrings(); + // ----------- Select Revision --------------------------- StringBuilder builder = new StringBuilder(); builder.append("SELECT "); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java index 38f76bfd27..dc8f036b9f 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerExporter.java @@ -32,6 +32,7 @@ import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; +import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.spi.server.InternalSession; @@ -184,7 +185,7 @@ public abstract class CDOServerExporter<OUT> protected void exportRevisions(final OUT out, CDOBranch branch) throws Exception { - repository.handleRevisions(null, branch, true, CDOBranchPoint.INVALID_DATE, false, new CDORevisionHandler.Filtered.Undetached(new CDORevisionHandler() + repository.handleRevisions(null, branch, true, CDOBranchPoint.INVALID_DATE, false, new CDORevisionHandler() { public boolean handleRevision(CDORevision revision) { @@ -198,7 +199,7 @@ public abstract class CDOServerExporter<OUT> throw WrappedException.wrap(ex); } } - })); + }); } protected abstract void exportRevision(OUT out, CDORevision revision) throws Exception; @@ -319,6 +320,11 @@ public abstract class CDOServerExporter<OUT> public static final String REVISION_REVISED = "revised"; + /** + * @since 4.7 + */ + public static final String REVISION_DETACHED = "detached"; + public static final String REVISION_RESOURCE = "resource"; public static final String REVISION_CONTAINER = "container"; @@ -497,6 +503,7 @@ public abstract class CDOServerExporter<OUT> protected void exportRevision(XMLOutput out, CDORevision revision) throws Exception { InternalCDORevision rev = (InternalCDORevision)revision; + boolean detached = rev instanceof DetachedCDORevision; out.element(REVISION); out.attribute(REVISION_ID, str(rev.getID())); @@ -510,6 +517,12 @@ public abstract class CDOServerExporter<OUT> out.attribute(REVISION_REVISED, revised); } + if (detached) + { + out.attribute(REVISION_DETACHED, true); + return; + } + CDOID resourceID = rev.getResourceID(); if (!CDOIDUtil.isNull(resourceID)) { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java index f4a3ea52eb..56b7189308 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java @@ -35,6 +35,7 @@ import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageLoader; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; +import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.spi.server.InternalRepository; @@ -421,32 +422,41 @@ public abstract class CDOServerImporter { CDOClassifierRef classifierRef = new CDOClassifierRef(attributes.getValue(REVISION_CLASS)); EClass eClass = (EClass)classifierRef.resolve(packageRegistry); - revision = (InternalCDORevision)CDORevisionFactory.DEFAULT.createRevision(eClass); - revision.setID(id(attributes.getValue(REVISION_ID))); - revision.setBranchPoint(branch.getPoint(Long.parseLong(attributes.getValue(REVISION_TIME)))); - revision.setVersion(Integer.parseInt(attributes.getValue(REVISION_VERSION))); - String revised = attributes.getValue(REVISION_REVISED); - if (revised != null) - { - revision.setRevised(Long.parseLong(revised)); - } - String resourceID = attributes.getValue(REVISION_RESOURCE); - if (resourceID != null) + CDOID id = id(attributes.getValue(REVISION_ID)); + int version = Integer.parseInt(attributes.getValue(REVISION_VERSION)); + long created = timeStamp(attributes.getValue(REVISION_TIME)); + long revised = timeStamp(attributes.getValue(REVISION_REVISED)); + boolean detached = "true".equals(attributes.getValue(REVISION_DETACHED)); + if (detached) { - revision.setResourceID(id(resourceID)); + revision = new DetachedCDORevision(eClass, id, branch, version, created, revised); } - - String containerID = attributes.getValue(REVISION_CONTAINER); - if (containerID != null) + else { - revision.setContainerID(id(containerID)); - } + revision = (InternalCDORevision)CDORevisionFactory.DEFAULT.createRevision(eClass); + revision.setID(id); + revision.setBranchPoint(branch.getPoint(created)); + revision.setVersion(version); + revision.setRevised(revised); + + String resourceID = attributes.getValue(REVISION_RESOURCE); + if (resourceID != null) + { + revision.setResourceID(id(resourceID)); + } - String featureID = attributes.getValue(REVISION_FEATURE); - if (featureID != null) - { - revision.setContainingFeatureID(Integer.parseInt(featureID)); + String containerID = attributes.getValue(REVISION_CONTAINER); + if (containerID != null) + { + revision.setContainerID(id(containerID)); + } + + String featureID = attributes.getValue(REVISION_FEATURE); + if (featureID != null) + { + revision.setContainingFeatureID(Integer.parseInt(featureID)); + } } } else if (FEATURE.equals(qName)) @@ -636,6 +646,16 @@ public abstract class CDOServerImporter return CDOIDUtil.read(str); } + protected final long timeStamp(String str) + { + if (str == null) + { + return CDOBranchPoint.UNSPECIFIED_DATE; + } + + return Long.parseLong(str); + } + protected Object value(Attributes attributes) { String type = attributes.getValue(FEATURE_TYPE); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java index b3042e3a15..e765c4c72f 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/BackupTest.java @@ -10,15 +10,19 @@ */ package org.eclipse.emf.cdo.tests; +import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.lob.CDOBlob; import org.eclipse.emf.cdo.common.lob.CDOClob; +import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionData; +import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.server.CDOServerExporter; import org.eclipse.emf.cdo.server.CDOServerImporter; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.tests.bundle.OM; +import org.eclipse.emf.cdo.tests.config.IRepositoryConfig; import org.eclipse.emf.cdo.tests.model1.Customer; import org.eclipse.emf.cdo.tests.model1.PurchaseOrder; import org.eclipse.emf.cdo.tests.model1.SalesOrder; @@ -40,6 +44,7 @@ import org.eclipse.net4j.util.io.IOUtil; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; @@ -567,6 +572,46 @@ public class BackupTest extends AbstractCDOTest System.out.println(customer2); } + @CleanRepositoriesBefore(reason = "Inactive repository required") + @Requires(IRepositoryConfig.CAPABILITY_BRANCHING) + public void testImportDetachedRevision() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/res1")); + PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder(); + purchaseOrder.setDate(new Date(1234567)); + resource.getContents().add(purchaseOrder); + transaction.commit(); + resource.getContents().clear(); + transaction.commit(); + session.close(); + + InternalRepository repo1 = getRepository(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CDOServerExporter.XML exporter = new CDOServerExporter.XML(repo1); + exporter.exportRepository(baos); + + InternalRepository repo2 = getRepository("repo2", false); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + CDOServerImporter.XML importer = new CDOServerImporter.XML(repo2); + importer.importRepository(bais); + + EClass eClass = getModel1Package().getPurchaseOrder(); + CDOSession session2 = openSession("repo2"); + CDOBranch branch = session2.getBranchManager().getMainBranch(); + session2.getRevisionManager().handleRevisions(eClass, branch, true, 0, false, new CDORevisionHandler() + { + public boolean handleRevision(CDORevision revision) + { + fail("No PurchaseOrder revision should be visible by now."); + return true; + } + }); + } + private Customer initExtResource(ResourceSet resourceSet) { resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl()); |