Hi;
I am trying to create a Confluence plugin that will store additional space attributes (such as space owner, backup space owners...). Initially I was storing the data in page labels and page content, but I would like to move it ideally to database.
I started playing with ActiveObject, but for some reason I am unable to store there object relationships.
Below is my code and console output with errors.
Any idea what could be wrong?
----------------
Space Attributes
package com.atlassian.confluence.msd.objects;
import com.atlassian.confluence.spaces.Space;
import com.atlassian.confluence.user.ConfluenceUser;
import net.java.ao.Entity;
import net.java.ao.OneToMany;
import net.java.ao.OneToOne;
public interface SpaceAttributes extends Entity {
@OneToOne
ConfluenceUser getSpaceOwner();
void setSpaceOwner(ConfluenceUser spaceOwner);
@OneToMany
ConfluenceUser[] getSpaceBackupOwners();
void setSpaceBackupOwners(ConfluenceUser[] spaceBackupOwners);
String getDivision();
void setDivision(String division);
String getDataClassification();
void setDataClassification(String dataClassification);
String getBusinessClassification();
void setBusinessClassification(String businessClassification);
@OneToOne
Space getSpace();
void setSpace(Space space);
}
Space Attributes Service
package com.atlassian.confluence.msd.services;
import com.atlassian.activeobjects.tx.Transactional;
import com.atlassian.confluence.msd.objects.SpaceAttributes;
import com.atlassian.confluence.spaces.Space;
import com.atlassian.confluence.user.ConfluenceUser;
import java.util.List;
@Transactional
public interface SpaceAttributesService {
SpaceAttributes add(Space space, ConfluenceUser spaceOwner, ConfluenceUser[] spaceBackupOwner, String division, String businessClassification, String dataClassification);
List<SpaceAttributes> all();
}
Space Attributes Service Impl
package com.atlassian.confluence.msd.services;
import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.confluence.msd.objects.SpaceAttributes;
import com.atlassian.confluence.spaces.Space;
import com.atlassian.confluence.user.ConfluenceUser;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
@Scanned
@Named
public class SpaceAttributesServiceImpl implements SpaceAttributesService {
@ComponentImport
private final ActiveObjects ao;
@Inject
public SpaceAttributesServiceImpl(ActiveObjects ao)
{
this.ao = checkNotNull(ao);
}
@Override
public SpaceAttributes add(Space space, ConfluenceUser spaceOwner, ConfluenceUser[] spaceBackupOwner, String division, String businessClassification, String dataClassification)
{
final SpaceAttributes spaceAttributes = ao.create(SpaceAttributes.class);
spaceAttributes.setSpace(space);
spaceAttributes.setSpaceOwner(spaceOwner);
spaceAttributes.setSpaceBackupOwners(spaceBackupOwner);
spaceAttributes.setDivision(division);
spaceAttributes.setBusinessClassification(businessClassification);
spaceAttributes.setDataClassification(dataClassification);
spaceAttributes.save();
return spaceAttributes;
}
@Override
public List<SpaceAttributes> all()
{
return newArrayList(ao.find(SpaceAttributes.class));
}
}
Listener
@EventListener
public void onSpaceBlueprintCreateEvent(SpaceBlueprintCreateEvent event) {
// Get space owners
String spaceOwner = event.getContext().get(GlobalConstants.SPACE_OWNER).toString();
ConfluenceUser spaceOwnerObject = userAccessor.getUserByName(spaceOwner.split(",")[0]);
// Get space backup owners
String spaceBackupOwners = event.getContext().get(GlobalConstants.SPACE_BACKUP_OWNER).toString();
ConfluenceUser[] spaceBackupOwnersObject = new ConfluenceUser[spaceBackupOwners.split(",").length];
for(int i = 0; i < spaceBackupOwners.split(",").length; i++) {
spaceBackupOwnersObject[i] = userAccessor.getUserByName(spaceBackupOwners.split(",")[i]);
}
String division = event.getContext().get(GlobalConstants.DIVISION).toString();
String businessClassification = event.getContext().get(GlobalConstants.BUSINESS_CLASSIFICATION).toString();
String dataClassification = event.getContext().get(GlobalConstants.DATA_CLASSIFICATION).toString();
spaceAttributesService = new SpaceAttributesServiceImpl(ao);
spaceAttributesService.add(event.getSpace(),spaceOwnerObject,spaceBackupOwnersObject,division,businessClassification,dataClassification);
}
Console Output
[INFO] [talledLocalContainer] Caused by: com.atlassian.activeobjects.internal.ActiveObjectsInitException: bundle [com.atlassian.confluence.msd.SpaceTemplates]
[INFO] [talledLocalContainer] at com.atlassian.activeobjects.osgi.TenantAwareActiveObjects$1$1$1.call(TenantAwareActiveObjects.java:95)
[INFO] [talledLocalContainer] at com.atlassian.activeobjects.osgi.TenantAwareActiveObjects$1$1$1.call(TenantAwareActiveObjects.java:86)
[INFO] [talledLocalContainer] at com.atlassian.sal.core.executor.ThreadLocalDelegateCallable.call(ThreadLocalDelegateCallable.java:38)
[INFO] [talledLocalContainer] at com.atlassian.confluence.impl.vcache.VCacheRequestContextManager.doInRequestContextInternal(VCacheRequestContextManager.java:87)
[INFO] [talledLocalContainer] at com.atlassian.confluence.impl.vcache.VCacheRequestContextManager.doInRequestContext(VCacheRequestContextManager.java:71)
[INFO] [talledLocalContainer] at com.atlassian.confluence.vcache.VCacheRequestContextOperations.lambda$withRequestContext$1(VCacheRequestContextOperations.java:59)
[INFO] [talledLocalContainer] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[INFO] [talledLocalContainer] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[INFO] [talledLocalContainer] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[INFO] [talledLocalContainer] ... 1 more
[INFO] [talledLocalContainer] Caused by: java.lang.RuntimeException: Unrecognized type: [Lcom.atlassian.confluence.user.ConfluenceUser;
[INFO] [talledLocalContainer] at net.java.ao.types.TypeManager.getType(TypeManager.java:73)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.getSQLTypeFromMethod(SchemaGenerator.java:406)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.parseFields(SchemaGenerator.java:311)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.parseInterface(SchemaGenerator.java:277)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.parseDDLRoots(SchemaGenerator.java:159)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.parseDDL(SchemaGenerator.java:141)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.generateImpl(SchemaGenerator.java:106)
[INFO] [talledLocalContainer] at net.java.ao.schema.SchemaGenerator.migrate(SchemaGenerator.java:84)
[INFO] [talledLocalContainer] at net.java.ao.EntityManager.migrate(EntityManager.java:128)
[INFO] [talledLocalContainer] at com.atlassian.activeobjects.internal.EntityManagedActiveObjects.migrate(EntityManagedActiveObjects.java:51)
[INFO] [talledLocalContainer] at com.atlassian.activeobjects.internal.AbstractActiveObjectsFactory$1.doInTransaction(AbstractActiveObjectsFactory.java:77)
[INFO] [talledLocalContainer] at com.atlassian.activeobjects.internal.AbstractActiveObjectsFactory$1.doInTransaction(AbstractActiveObjectsFactory.java:72)
[INFO] [talledLocalContainer] at com.atlassian.sal.core.transaction.HostContextTransactionTemplate$1.doInTransaction(HostContextTransactionTemplate.java:21)
[INFO] [talledLocalContainer] at com.atlassian.sal.spring.component.SpringHostContextAccessor$1.doInTransaction(SpringHostContextAccessor.java:71)
[INFO] [talledLocalContainer] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
[INFO] [talledLocalContainer] at com.atlassian.sal.spring.component.SpringHostContextAccessor.doInTransaction(SpringHostContextAccessor.java:68)
[INFO] [talledLocalContainer] at com.atlassian.confluence.spring.transaction.interceptor.ConfluenceSpringHostContextAccessor.access$001(ConfluenceSpringHostContextAccessor.java:21)
[INFO] [talledLocalContainer] at com.atlassian.confluence.spring.transaction.interceptor.ConfluenceSpringHostContextAccessor.lambda$doInTransaction$3(ConfluenceSpringHostContextAccessor.java:72)
[INFO] [talledLocalContainer] at com.atlassian.confluence.impl.vcache.VCacheRequestContextManager.doInRequestContextInternal(VCacheRequestContextManager.java:87)
[INFO] [talledLocalContainer] at com.atlassian.confluence.impl.vcache.VCacheRequestContextManager.doInRequestContext(VCacheRequestContextManager.java:71)
[INFO] [talledLocalContainer] at com.atlassian.confluence.spring.transaction.interceptor.ConfluenceSpringHostContextAccessor.doInTransaction(ConfluenceSpringHostContextAccessor.java:72)
[INFO] [talledLocalContainer] at sun.reflect.GeneratedMethodAccessor242.invoke(Unknown Source)
Hello Miroslav,
Congratulations on starting the undertaking to create a Confluence add-on.
Something to be aware of is this is a support community and not often browsed by developers. We want to ensure you get the responses and answers you need so we would suggest you check out the Developer Community. The Developer Community may have more available resources to answer or address your developer questions.
Regards,
Stephen Sifers
Hello Stephen, thanks for the reminder. It looks like I overlooked it, as I was in impression I created it in developer community.
I re-created the article there. thanks.
Best regards, Miroslav
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.