cancel
Showing results for 
Search instead for 
Did you mean: 

Cound not Create Site in Alfresco Share programmatically

sselvan
Champ in-the-making
Champ in-the-making
I am trying to create a Site in Alfresco Share, programmatically.

      SiteInfo siteInfo = this.serviceRegistry.getSiteService().createSite("TestSite", "1234567", "for-santhana", "description", true);
      System.out.println("successful site, and the details are "+" preset= "+siteInfo.getSitePreset()+" shortname= "+siteInfo.getShortName());

The problem is - the site is getting created in Alfresco under Sites directory, but when I open the same in Alfresco Share, it does not open with dashboard, document library, wiki, blog etc.,

If you have any clues, please let me know. This will be a great help!!
16 REPLIES 16

mikeh
Star Contributor
Star Contributor
Take a look at how Share does it - there's some Web Tier work to be done too to create the Site preset.

Have a look at create-site.js and create-site.post.json.js

Thanks,
Mike

sselvan
Champ in-the-making
Champ in-the-making
I did look into the way Share itself creating site.
But, that was in JavaScript and using YUI etc., So, I don't think I can reuse that for my java code.

C:\Alfresco\tomcat\webapps\share\modules\create-site.js

please advice. thank you

sselvan
Champ in-the-making
Champ in-the-making
UPDATE:

I need to programmatically create a site in Share, using the API – either by JavaScript or Java.

I was able to create a site in Share programmatically, and the site is listed in Share as one of the sites. But, the problem is – when I click on the site to go inside the Site in Share using the User Interface, it does not take me anywhere.

As I understand the Site object is created, but the “components” needed are not being loaded. I mean when I click on the site name, it should open the dashboard of the site – but it is not doing it.

I am not finding any code or API for this. There is no method to add "components" to the site (I checked in the SiteService – both in JavaScript and Java API).

kevinr
Star Contributor
Star Contributor
As Mike said above, you need to call code in Share to do it (which itself will call the repo to create the site folder). He does not mean Share client-side code, but a Share webscript, the one you want is:
http://<yourserver>/share/service/index/uri/modules/create-site
Take a look at the POST webscript at the bottom of the page, you need to POST it a JSON object containing the details of the Site you want to create - that is all that the Share client-side javascript code does via an AJAX call. So take a look at root\projects\slingshot\source\web\modules\create-site.js (in the SVN codebase) which can be used as an example of how to build up the JSON object excepted by the Share webscript.

Thanks,

Kev

alexander
Champ in-the-making
Champ in-the-making
Alfresco Share creates dashboard presets in the AVM store. These are specially named xml files (with some content from presets.xml).

If you are brave enough to create these files in AVM store using your code you can explore current presets for manually created sites using node browser.

This approach is tested.

flefoll
Champ in-the-making
Champ in-the-making
Hi,

We have the same need,
Any already done code to successfully create programmatically Share Sites will be more than welcome.

Thanks in advance,

Francois

gil_fernandes
Champ in-the-making
Champ in-the-making
We have created a Java-based Alfresco webscript in a module which creates programmatically an Alfresco Share site for a specific user. The webscript has two main components: one Java class and a Javascript file.

This is what the Java class does:

  • create the user in the Alfresco repository

  • transform and save the user dashboard files in the AVM store (this is the most complex step in the whole implementation)
This is what the Javascript file does:

  • Creates the site using the "siteService" that is exposed to the Javascript API
This is the main bit of the Java code we used to create the user and save the user dashboard files to the AVM store:


         UserTransaction tx = null;
         final TransactionService transactionService = serviceRegistry
               .getTransactionService();
         try {
            tx = transactionService.getUserTransaction();
            tx.begin();
            if(repositoryAuthenticationDao.getUserOrNull(username) != null) {
               setStatus(model, com.onepoint.businesshr.model.Status.USER_EXISTS, status);
               tx.rollback();
            }
            else {
               password = genPassword(password);
               NodeRef personNodeRef = createUser(email, username, firstName,
                     lastName, password);
               setStatus(model, com.onepoint.businesshr.model.Status.SUCCESS, status);
               model.put(PERSON_REF_PARAM, personNodeRef);
               createDashBoard(clientName, res);
               tx.commit();
            }
         } catch (Throwable t) {
            LOG.error("Could not create user.", t);
            setStatus(model, com.onepoint.businesshr.model.Status.ERROR, status);
            if (tx != null) {
               try {
                  tx.rollback();
               } catch (Exception e) {
                  LOG.warn("Could not rollback transaction.", e);
               }
            }
         }

I will not go too much into detail on how you can create the user in Alfresco here. I think there is enough information in the forums on how to do this.

The most tricky bit was like what i mentioned to save the dashboard files to the AVM store. This is required for the Alfresco Share site to be rendered successfully. The main function that creates these files in the code is:


       /**
    * Creates the dashboard.
    * @param userName The user name.
    * @param res The webscript response.
    * @throws IOException Thrown in case the dashboard cannot be created.
    */
   private void createDashBoard(String userName, WebScriptResponse res) throws IOException {
      
      final String dashboardTitle = String.format(dashboardPathTemplate, userName);
      final Resource dashboardResource = new ClassPathResource("alfresco/module/businesshr/templates/dashboard.xml");
      final InputStream dashboardIn = dashboardResource.getInputStream();
      if(dashboardIn != null) {
         avmRemoteStore.createDocument(res, SITE_STORE,
               dashboardTitle, dashboardIn);
         for(FreeMarkerProcessor processor : freeMarkerProcessorList) {
            final StringBuilder pathBuilder = new StringBuilder(100);
            try {
               final ByteArrayInputStream renderedTemplateIn = processor.render(userName, pathBuilder);
               avmRemoteStore.createDocument(res, SITE_STORE,
                     pathBuilder.toString(), renderedTemplateIn);
            } catch (TransformerException e) {
               LOG.warn("Could not transform part. " +
                     "Some parts of the user interface will not be available for " + userName, e);
            }
            
         }
      }
   }

alfresco/module/businesshr/templates/dashboard.xml is actually the main dashboard definition file with the dashboard layout definition and looks in our case like this:


<?xml version="1.0" encoding="UTF-8"?>

<page>
  <title>Collaboration Site Dashboard</title>
  <description>Collaboration site's dashboard page</description>
  <authentication>user</authentication>
  <template-instance>dashboard-1-column</template-instance>
  <properties>
    <sitePages>[{"pageId":"wiki-page"}, {"pageId":"blog-postlist"}, {"pageId":"documentlibrary"}, {"pageId":"calendar"},{"pageId":"links"}, {"pageId":"discussions-topiclist"}]</sitePages>
  </properties>
</page>

This is not the only file that we have to save to the AVM store so that the dashboard is rendered correctly. You will need more files which need to be slightly changed and also saved to the AVM store. One of these files that needs to be stored to the AVM store is the page with the title. The template we had to render that page is:

<?xml version="1.0" encoding="UTF-8"?>

<component>
  <guid>page.title.site~${siteid}~dashboard</guid>
  <scope>page</scope>
  <region-id>title</region-id>
  <source-id>site/${siteid}/dashboard</source-id>
  <url>/components/title/collaboration-title</url>
</component>

Of course in this template ${siteid} must be replaced by the user name. And the rendered template must also be stored in this path:

/alfresco/site-data/components/page.title.site~%s~dashboard.xml

where %s needs to be replaced by the name of the user that is the owner of the site.

The Javascript file essentially calls the siteService to create the site. Here is the relevant code:

   // Create the site 
   var site = siteService.createSite(sitePreset, shortName, title, description, isPublic);

   …
   
   site.setMembership(userName, "SiteManager");

csrajuse
Champ in-the-making
Champ in-the-making
Where is all the data related to generation of a site being stored? Is it there in Alfresco's database ? or stored in some XML files.

I came here with an impression like creating a share site will be something very straight forward like calling a service like

something like …

int shareSiteId = ShareService.createShare(int userId); ///where userId will be the owner of the site.
ShareService.associateMember(int userId, ShareService.SITE_MANAGER_ROLE); //Manager for the site.
ShareService.setDocumentLibrary(boolean visible, int shareSiteId);// where we are telling share that this needs to be visible when user logs into the site.

ofcorse all this wrapped in some SOAP or REST service.

I come from J2EE world and am new to Alfresco. Based on the previous message seems like there is some javascript code to be called based on a client side event (some action needs to trigger it)

For me all this generation will be happening on a server side in my own j2ee application so ideally I will be calling some REST service or (bunch of them) and wrapping them in a transaction.

Is there any solution like that?

Problem for me is even if I want to call a javascript function from my server.. I will be in a different JVM and not possible.

Sorry for the lengthy glib.

csrajuse
Champ in-the-making
Champ in-the-making
Ummm , crude but might work , may be I should intercept all the calls made from the browser to Alfresco while creating a share site(using some tcpmon or some tool) and call it using URLConnection and see how it works… will update if it works.