Artifact deploy in the local repository (Repo A) is forced to be in GAVC layout controlled using the user plugin.
We would like to differentiate all the Production released artifacts by copying them to another repository (Repo B).
How do I restrict the copy should happen only at the version level directory in GAVC (GroupId/ArtifactId/Version/Classifier) structure.
Below code works for me to restrict any copy at GroupId/ArtifactId folder level.
beforeCopy { item, targetRepoPath, properties ->
if (item.repoKey.equals("RepoA")){
if (item.repoPath.isFolder()){
def lastChild = repositories.getChildren(item.repoPath).last().repoPath
def childLayoutInfo = repositories.getLayoutInfo(lastChild)
String childGroupId = childLayoutInfo.getOrganization()
String childArtifactId = childLayoutInfo.getModule()
String childVersionId = childLayoutInfo.getBaseRevision()
if ( "${childGroupId}" == "null" || "${childArtifactId}" == "null" || "${childVersionId}" == "null" ) {
throw new CancelException("Copy not permitted at this level")
}
}
}
}
I would also like to restrict a copy request directly triggered at the File/Classifier level as well.
Related
I have a project that uses TypeSafe config. It loads multiple configuration files. One is loaded the easy way:
private val config = ConfigFactory.load( "test-parameters" )
This one seems to honor the foo = ${?ENV_VAR} override syntax, whether ENV_VAR is passed in via the environment, or via Java System Properties (-DXXX=).
The other config file(s) are loaded using .parseResources() followed by an eventual .resolve(). The override syntax works fine if the variables are specified as environment variables, but nothing happens when they are system properties. The code looks like this:
// we define a layered config, so that you can define values in one layer, and customize them in another
// if your environment includes sub-folders, config files are read from deepest folder first
// so that you can define values in the higher folders and override them in the more specific folder
// e.g. if the environment is "foo/bar/baz", then the order of loading config files is:
// * application.conf
// * conf/foo/bar/baz/config.conf
// * conf/foo/bar/config.conf
// * conf/foo/config.conf
// * default.conf
def loadConfig(env: String): Config = {
// do not allow the user to supply a relative path that tries to escape the conf directory hierarchy
if (env != null && env.matches("(?:^|/)\\.\\./"))
throw new Exception("Illegal Environment String")
var c = userConfig
if (env != null && env != "") {
val parts = env.split("/")
var n = parts.length
while (n > 0) {
c = c.withFallback(ConfigFactory.parseResources(environmentConfigFile(parts.take(n).mkString("/"))))
n -= 1
}
}
c.withFallback(defaultConfig).resolve()
}
def loadConfig: Config = loadConfig(Test.environment)
At first blush, it looks like a bug. .parseResources().resolve() and .load() behave slightly differently.
Or did I just miss something?
The problem is the lack of ConfigFactory.load(), which automatically merges in the system properties.
By changing the initialization, as follows, it works as intended:
var c = ConfigFactory.load().withFallback( userConfig )
YAY!
I want a sub folder within Document library as rootNode in Alfresco Shave 4.2
For Example In Document Library the folder path is Documents > XYZ > User1. When user accesses Document Library by default the content in Documents > XYZ > User1 should be displayed instead of content in Document. If we customize rootNode property from below code which is part of toobar.get.js it should work..I replaced rootNode with XYZ and it works. But rootNode="XYZ/User1" does not work
Not sure how to speciy the sub folder ?
var docListToolbar = {
id: "DocListToolbar",
name: "Alfresco.DocListToolbar",
options: {
siteId: (page.url.templateArgs.site != null) ? page.url.templateArgs.site :"",
rootNode: toolbar.rootNode != null ? toolbar.rootNode : "",
hideNavBar: Boolean(toolbar.preferences.hideNavBar),
googleDocsEnabled: toolbar.googleDocsEnabled,
repositoryBrowsing: toolbar.rootNode != null,
useTitle: (useTitle == "true"),
syncMode: toolbar.syncMode != null ? toolbar.syncMode : "",
createContentByTemplateEnabled: model.createContentByTemplateEnabled,
createContentActions: model.createContent
}
};
model.widgets = [docListToolbar];
since edit online is not present in My Files we created a cutom site in Alfreso Share as a custom My Files section.
Maybe it's a bit late but I would suggest to create a custom site page, almost the same as document library, but with changed root node. And then you can easily replace Document Library page with custom one in site settings.
I have a quite nice example here: http://streetturtle.ninja/jekyll/update/2014/10/23/alf-custom-doclibrary-site-page/. It is almost the same as you want, but the root node changes according to the logged user.
How to get path of file which isn't in newest version but is a part of previous changelist in RTC scm.
All I could achieve so far is this:
IFileItemHandle fileItemHandle = (IFileItemHandle) IFileItem.ITEM_TYPE.createItemHandle(change.afterState().getItemId(), change.afterState().getStateId());
file = versionableManager.fetchCompleteState(fileItemHandle, monitor);
if (file instanceof IFolder) {
IFolder folder = (IFolder) file;
relativePath = getFilePath(file, workspaceConnection.configuration(changeSet.getComponent()), monitor);
fileName = folder.getName();
} else {
relativePath = getFilePath(file, workspaceConnection.configuration(changeSet.getComponent()), monitor);
fileName = ((FileItem) file).getName();
}
Where getFilePath is:
private String getFilePath(IVersionableHandle folder, IConfiguration config, IProgressMonitor monitor, Boolean searchInHistory) throws TeamRepositoryException {
List lst = new ArrayList<IVersionableHandle>(), ancestors;
lst.add(folder);
if (searchInHistory) {
ancestors = config.determineAncestorsInHistory(lst, monitor);
} else {
ancestors = config.locateAncestors(lst, monitor);
}
return getFullPath(ancestors);
}
private String getFullPath(List ancestor) throws TeamRepositoryException {
String directoryPath = "";
for (Object ancestorObj : ancestor) {
IAncestorReport ancestorImpl = (IAncestorReport) ancestorObj;
for (Object nameItemPairObj : ancestorImpl.getNameItemPairs()) {
INameItemPair nameItemPair = (INameItemPair) nameItemPairObj;
String pathName = nameItemPair.getName();
if (pathName != null && !pathName.equals("")) {
directoryPath = directoryPath + "\\" + pathName;
}
}
}
return directoryPath;
}
Unfortunately it doesn't work perfectly. If filename is changed in following changelists like on this example:
Changelist 1:
add file: src/newFile.java
Changelist 2:
modify file: src/newFile.java
Changelist 3:
rename file: src/newFile.java -> src/newFile_rename.java
The relative path resolved in first changelist would be:
src/newFile_rename.java
instead of
src/newFile.java
How to make it works good?
While the javadoc for IConfiguration.determineAncestorsInHistory doesn't specify, the server side equivalent IScmService.configurationDetermineAncestorsInHistory (which is what ends up being called) says this in the javadoc:
* #param versionableItemHandles
* a list of versionable items; only the item ids are needed;
* must not be <code>null</code>
Basically, the determineAncestorsInHistory is not looking at the state id on the file handles, it only looks at the item id.
The particular state of the file that will be considered is determined by the configuration. This is mostly because while the state of the file in the changeset will tell you the name of that file, it does not tell you the name of the parent folder. That will depend on the state of the folder that is present in the workspace at a particular time and could be different for different workspaces
You basically need to get an IConfiguration that represents your workspace at the time the change set was accepted/created.
The way I see to do this is to get the IWorkspaceConnection.changeHistory(component) (this is actually defined on IFlowNodeConnection). You will need to walk back through the histories by calling IChangeHistory.previousHistory(monitor) until you find one that contains your changeset in IChangeHistory.recent(monitor).
Once you find the appropriate IChangeHistory use IChangeHistory.configuration() for the determineAncestorsInHistory call.
Note that this configuration represents the state of the workspace at the end of that particular IChangeHistory, so to be completely accurate you would need to inspect the changesets that occur after your change in the IChangeHistory.recent to see if any of them modified your file name (or also any of the containing folders' file names).
(Another alternative is to use the history configuration 1 previous to the history that contains your changeset, and then look at the effects of the changes that happen before your change)
I have the following update method, which seems to be working:
public Folder UpdateFolder(Folder folder)
{
Folder serverFolder = _db.Folders.FirstOrDefault(f => f.FolderId == folder.FolderId);
if (serverFolder != null)
{
serverFolder.Title = folder.Title;
serverFolder.Details = folder.Details;
}
SaveChanges();
return serverFolder;
}
I just noticed that most Update methods I've read about have calls to Entry.StateDetached and StateAttached - is what I've done above ok, or am I missing something?
It is okay. _db.Folders.FirstOrDefault reads the Folder and it is attached to the context.
You would need to check if the entity was attached if you were simply passing in a Folder (without reading) and attempting to update it.
Basically, Folder serverFolder = _db.Folders.FirstOrDefault(f => f.FolderId == folder.FolderId); ensures that the Folder is attached so you don't have to worry.
I think you need to do _db.SaveChanges(); instead of SaveChanges();
I can get strings representing group and user permissions for a given folder with the following.
Code
// assumes Core Service client "client"
var folderData = client.Read("tcm:5-26-2", new ReadOptions()) as FolderData;
var accessControlEntryDataArray =
folderData.AccessControlList.AccessControlEntries;
Console.WriteLine(folderData.Title);
foreach (var accessControlEntryData in accessControlEntryDataArray)
{
Console.WriteLine("{0} has {1}",
accessControlEntryData.Trustee.Title,
accessControlEntryData.AllowedPermissions.ToString());
}
Output
Some Folder
Everyone has Read
Editor has None
Chief Editor has None
Publication Manager has None
Interaction Manager has None
T2011-CB-R2\areyes has All
[scope] Editor 020 Create has Read, Write
T2011-CB-R2\local1 has Read, Write, Delete
[rights] Author - Content has None
Seems like the four possible values for `AllowedPermissions are:
None
Read
Read, Write
Read, Write, Delete
All
This works great for my use case to create a folder permissions report. I can .Replace() these to a familiar notation (e.g. rw-- or rwdl).
But is manipulating these string values the right approach to set permissions as well? I'd imagine I'd want objects or maybe enums instead. Could someone point me in the right direction?
Also I noticed I get some, but not all non-applicable groups set as None. I don't specifically need them here, but I'm curious at what determines whether those get returned--did I miss something in my code?
Rights and Permissions are enums, indeed. You can set using the method below. If you want to set multiple rights you should do something like "Rights.Read | Rights.Write"
Keep in mind that this method will return you object that you have to save \ update \ create after
public static OrganizationalItemData SetPermissionsOnOrganizationalItem(
OrganizationalItemData organizationalItem,
TrusteeData trustee,
Permissions allowedPermissions,
Permissions deniedPermissions = Permissions.None)
{
if (organizationalItem.AccessControlList == null)
{
organizationalItem.AccessControlList
= new AccessControlListData
{AccessControlEntries = new AccessControlEntryData[0]};
}
var entries = organizationalItem.AccessControlList
.AccessControlEntries.ToList();
// First check if this trustee already has some permissions
var entry = entries.SingleOrDefault(
ace => ace.Trustee.IdRef == trustee.Id);
if (entry != null)
{
// Remove this entry
entries.Remove(entry);
}
entries.Add(new AccessControlEntryData
{
AllowedPermissions = allowedPermissions,
DeniedPermissions = deniedPermissions,
Trustee = new LinkToTrusteeData { IdRef = trustee.Id }
});
organizationalItem.AccessControlList.AccessControlEntries
= entries.ToArray();
return organizationalItem;
}