SharePoint 2007 Object Model: How can I make a new site collection, move the original main site to be a subsite of the new site collection? - sharepoint

Here's my current setup:
one site collection on a SharePoint 2007 (MOSS Enterprise) box (32 GB total in size)
one main site with many subsites (mostly created from the team site template, if that matters) that is part of the one site collection on the box
What I'm trying to do*:
**If there is a better order, or method for the following, I'm open to changing it*
Create a new site collection, with a main default site, on same SP instance (this is done, easy to do in SP Object Model)
Move rootweb (a) to be a subsite in the new location, under the main site
Current structure:
rootweb (a)
\
many sub sites (sub a)
What new structure should look like:
newrootweb(b)
\
oldrootweb (a)
\
old many sub sites (sub a)
Here's my code for step #2:
Notes:
* SPImport in the object model under SharePoint.Administration, is what is being used here
* This code currently errors out with "Object reference not an instance of an object", when it fires the error event handler
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Deployment;
public static bool FullImport(string baseFilename, bool CommandLineVerbose, bool bfileCompression, string fileLocation, bool HaltOnNonfatalError,
bool HaltOnWarning, bool IgnoreWebParts, string LogFilePath, string destinationUrl)
{
#region my try at import
string message = string.Empty;
bool bSuccess = false;
try
{
SPImportSettings settings = new SPImportSettings();
settings.BaseFileName = baseFilename;
settings.CommandLineVerbose = CommandLineVerbose;
settings.FileCompression = bfileCompression;
settings.FileLocation = fileLocation;
settings.HaltOnNonfatalError = HaltOnNonfatalError;
settings.HaltOnWarning = HaltOnWarning;
settings.IgnoreWebParts = IgnoreWebParts;
settings.IncludeSecurity = SPIncludeSecurity.All;
settings.LogFilePath = fileLocation;
settings.WebUrl = destinationUrl;
settings.SuppressAfterEvents = true;
settings.UpdateVersions = SPUpdateVersions.Append;
settings.UserInfoDateTime = SPImportUserInfoDateTimeOption.ImportAll;
SPImport import = new SPImport(settings);
import.Started += delegate(System.Object o, SPDeploymentEventArgs e)
{
//started
message = "Current Status: " + e.Status.ToString() + " " + e.ObjectsProcessed.ToString() + " of " + e.ObjectsTotal + " objects processed thus far.";
message = e.Status.ToString();
};
import.Completed += delegate(System.Object o, SPDeploymentEventArgs e)
{
//done
message = "Current Status: " + e.Status.ToString() + " " + e.ObjectsProcessed.ToString() + " of " + e.ObjectsTotal + " objects processed.";
};
import.Error += delegate(System.Object o, SPDeploymentErrorEventArgs e)
{
//broken
message = "Error Message: " + e.ErrorMessage.ToString() + " Error Type: " + e.ErrorType + " Error Recommendation: " + e.Recommendation
+ " Deployment Object: " + e.DeploymentObject.ToString();
System.Console.WriteLine("Error");
};
import.ProgressUpdated += delegate(System.Object o, SPDeploymentEventArgs e)
{
//something happened
message = "Current Status: " + e.Status.ToString() + " " + e.ObjectsProcessed.ToString() + " of " + e.ObjectsTotal + " objects processed thus far.";
};
import.Run();
bSuccess = true;
}
catch (Exception ex)
{
bSuccess = false;
message = string.Format("Error: The site collection '{0}' could not be imported. The message was '{1}'. And the stacktrace was '{2}'", destinationUrl, ex.Message, ex.StackTrace);
}
#endregion
return bSuccess;
}
Here is the code calling the above method:
[TestMethod]
public void MOSS07_ObjectModel_ImportSiteCollection()
{
bool bSuccess = ObjectModelManager.MOSS07.Deployment.SiteCollection.FullImport("SiteCollBAckup.cmp", true, true, #"C:\SPBACKUP\SPExports", false, false, false, #"C:\SPBACKUP\SPExports", "http://spinstancename/TestImport");
Assert.IsTrue(bSuccess);
}

Instead of trying to code this up, have you tried to use the SharePoint Content Deployment Wizard from Codeplex?
Export your current hierarchy, and import it to the new place using this tool.
Regards,
M

Related

how to get value after the record has been save?

I have an issue after saving the record in Stock Items screen, it doesn't work the way I want it to work.
I want to get the concatenated values after saving the record.
I customized the description field to concatenate the values ​​of some attributes.
I have all the following code inside RowPersisted event, the way I get that data is by using BQL query:
protected void InventoryItem_RowPersisted(PXCache cache, PXRowPersistedEventArgs e, PXRowPersisted InvokeBaseHandler)
{
string attr = "";
string itemClassDesc = "";
string itemClassCD = "";
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (InventoryItem)e.Row;
PXResultset<InventoryItem> result =
PXSelectJoin<InventoryItem,
InnerJoin<CSAnswers,
On<CSAnswers.refNoteID, Equal<InventoryItem.noteID>>,
LeftJoin<CSAttributeDetail,
On<CSAttributeDetail.attributeID, Equal<CSAnswers.attributeID>,
And<CSAttributeDetail.valueID, Equal<CSAnswers.value>>>,
InnerJoin<CSAttribute,
On<CSAttribute.attributeID, Equal<CSAnswers.attributeID>>>>>,
Where<InventoryItem.inventoryID, Equal<Current<InventoryItem.inventoryID>>>,
OrderBy<Asc<CSAnswers.attributeID>>>.Select(this.Base);
foreach (PXResult<InventoryItem, CSAnswers, CSAttributeDetail, CSAttribute> record in result)
{
InventoryItem inventory = (InventoryItem)record;
CSAnswers answers = (CSAnswers)record;
CSAttributeDetail detail = (CSAttributeDetail)record;
CSAttribute attribute = (CSAttribute)record;
switch (itemClassCD)
{
case "0531":
if (attribute.AttributeID == "A1" || attribute.AttributeID == "A2" || attribute.AttributeID == "A3")
{
if (attribute.AttributeID == "A2")
attr += answers.Value + " ";
else
if (attribute.ControlType == 1)
attr += attribute.Description + " " + answers.Value + " ";
else
attr += attribute.Description + " " + detail.Description + " ";
}
break;
default:
break;
}
}
cache.SetValue<InventoryItem.descr>(row, itemClassDesc + " " + attr);
}
It works well because the description field concatenates the values when I press the save button but it always get a previous record.
Can you help me with this?
Thanks!
The RowPersisted event is fired after the item has been saved. You need to use the RowPersisting event or override the Persist function of the graph and run your code before invoking the base function.

I have this array class that is not removing items after re-running my recyclerview

The below class is used in an array.
package com.example.ShivitoMGO;
public class RoomTable {
public String RoomName,UpDown,minmaxint;
}
Main Activity
static ArrayList <RoomTable> CountCheck = new ArrayList<>();
public void playerup(View vvv){
st_spinner = v1.findViewById(R.id.spinner);
st_reportLayout = v1.findViewById(R.id.reportlayout);
st_Leanervidimg = v1.findViewById(R.id.Linearvidcopy);
TextView roomname = v1.findViewById(R.id.action_Players1);
RoomTable roomtb = new RoomTable();
if (CountCheck.size() == 0){
//playerupdown = "up";
Toast.makeText(this, "Will notify when " + mRooms.get(position1) + " players increase #" + mRoomSize.get(position1), Toast.LENGTH_LONG).show();
String[] minmaxval = mRoomSize.get(position1).split("/");
CountCheckint = Integer.parseInt(minmaxval[0].trim());
//CountCheck = (String) mRooms.get(position1);
roomtb.RoomName = (String) mRooms.get(position1);
roomtb.minmaxint = minmaxval[0].trim();
roomtb.UpDown = "up";
Log.d("added: ", "it was added");
CountCheck.add(roomtb);
Log.d("RoomTableadd: ",roomtb.RoomName+ " " + roomtb.minmaxint +" " +roomtb.UpDown);
st_reportLayout.setVisibility(View.GONE);
Log.d("Longclickhere: ", mRoomSize.get(position1));
Log.d("RoomNameCount ", String.valueOf(CountCheck.get(0).RoomName));
}else {
int exist1 = 0;
int poss;
for (int i = 0; i < CountCheck.size(); i++) {
if (roomname.getText() == CountCheck.get(i).RoomName) {
Log.d("RoomNametxt: " , CountCheck.get(i).RoomName);
Log.d("RoomNametxt: ", (String) roomname.getText());
Toast.makeText(this, "Notification " + CountCheck.get(i).RoomName + " OFF!", Toast.LENGTH_LONG).show();
Log.d("Removed item: ", String.valueOf(CountCheck.size()));
CountCheck.remove(i);
Log.d("Removed item: ", String.valueOf(CountCheck.size()));
st_reportLayout.setVisibility(View.GONE);
exist1 = 1;
poss = i;
} else {
exist1 = 0;
}
}
if (exist1 == 0) {
Toast.makeText(this, "Will notify when " + mRooms.get(position1) + " players increase #" + mRoomSize.get(position1), Toast.LENGTH_LONG).show();
String[] minmaxval = mRoomSize.get(position1).split("/");
CountCheckint = Integer.parseInt(minmaxval[0].trim());
//CountCheck = (String) mRooms.get(position1);
roomtb.RoomName = (String) mRooms.get(position1);
roomtb.minmaxint = minmaxval[0].trim();
roomtb.UpDown = "up";
Log.d("added: ", "it was added");
CountCheck.add(roomtb);
Log.d("RoomTableadd: ", roomtb.RoomName + " " + roomtb.minmaxint + " " + roomtb.UpDown);
st_reportLayout.setVisibility(View.GONE);
}
Log.d("CountSize: ", String.valueOf(CountCheck.size()));
for (int xb = 0;xb<CountCheck.size();xb++) {
try {
Log.d("RoomNameCount ", String.valueOf(CountCheck.get(xb).RoomName));
} catch (Exception e) {
Log.d("Out of range ", String.valueOf(e));
}
}
}
}
Recycler-View
#Override
public boolean onLongClick(View v) {
// Launch your web intent
if (CountCheck.size() != 0){
Log.d("Longclickhere: ",mRoomSize.get(position));
Toast.makeText(mContext, mRoomSize.get(position), Toast.LENGTH_SHORT).show();
Toast.makeText(mContext, "Will notify when "+mRooms.get(position)+" players decrease", Toast.LENGTH_SHORT).show();
String[] minmaxval = mRoomSize.get(position).split("/");
MainActivity.CountCheckint = Integer.parseInt(minmaxval[0].trim());
} else{
//MainActivity.CountCheck = "";
Toast.makeText(mContext, "Player Decrease notification OFF", Toast.LENGTH_SHORT).show();
}
return true;
In this app the recycler view creates the "rooms" and if the room is selected the textview and 2 other values are put in to the RoomTable. these are stored and used in a service to check if ether of the other to values change. Everything works as intended unless i use the swip-to-refresh witch runs the recycler-view again. If i do not refresh and i select the same item in the recycler-view it will remove it from CountCheck . However if i run the refresh and select the same recycler-view item that i selected previously it will add it instead of removing it. This Makes no since to me because i use a for loop to Check the CountCheck.get(i).RoomName aka the textview and if the names are the same then my if statement will remove instead of add. is it somehow possible i'm ending up with 2 CountCheck Objects????? with the same name???? Please I'm out of ideas on this one. Thanks.
I dont remember why. Maybe someone can explain but i changed this line
if (roomname.getText() == CountCheck.get(i).RoomName)
To this
if (roomname.getText().equals(CountCheck.get(i).RoomName));
and that fixed the issue. please let me know the difference if you are reading this.

ExtLibUtil.getCurrentSessionAsSigner open mail.box

Opening mail.box with ExtLibUtil.getCurrentSessionAsSigner does not work for mail.box.
All elements are signed with the same id.
I'd like to copy mails, created by Anonymous, to mail.box. Any ideas, workarounds?
package de.egvpb.surveys;
import java.io.Serializable;
import lotus.domino.Database;
import lotus.domino.Session;
import com.ibm.xsp.extlib.util.ExtLibUtil;
public class SessionAsSignerBean implements Serializable{
private static final long serialVersionUID = 1L;
private Database mailBoxDb ;
public SessionAsSignerBean(){
this.mailBoxDb = this.getMailBoxDbAsSigner() ;
}
private Database getMailBoxDbAsSigner() {
Session s = ExtLibUtil.getCurrentSessionAsSigner() ;
Database result = null ;
Database currentDb = null ;
String server = "" ;
String filepath = "" ;
try {
// Anonymous has reader access for currentDb; database is opend
currentDb = s.getCurrentDatabase() ;
if( currentDb.isOpen() ) {
System.out.println( "getMailBoxDbAsSigner, currentDB is open: " + currentDb.getFilePath() + " on " + currentDb.getServer() );
} else {
System.out.println( "getMailBoxDbAsSigner, currentDB is NOT open");
}
server = currentDb.getServer() ;
// Anonymous has no Access for names.nsf; database is opend
filepath = "names.nsf" ;
result = s.getDatabase(server, filepath) ;
if( result.isOpen() == false ) {
System.out.println( "getMailBoxDbAsSigner, failed to open database " + filepath + " on " + server );
} else {
System.out.println( "getMailBoxDbAsSigner, database opend " + filepath + " on " + server );
}
// Anonymous has no Access for mail.box; database is NOT opend
filepath = "mail.box" ;
result = s.getDatabase(server, filepath) ;
if( result.isOpen() == false ) {
System.out.println( "getMailBoxDbAsSigner, failed to open database " + filepath + " on " + server );
} else {
System.out.println( "getMailBoxDbAsSigner, opend database " + filepath + " on " + server );
}
} catch (Exception e) {
e.printStackTrace() ;
}
return result ;
}
// ====
public Database getMailBoxDb() {
return mailBoxDb;
}
public void setMailBoxDb(Database mailBoxDb) {
this.mailBoxDb = mailBoxDb;
}
}
I can't see anything wrong in your code, although for best practice I would recommend setting server to s.getServerName(), "" has different meanings for XPiNC.
Does your signer have access to mail.box? This should work and I've used such code before, amongst other places in XPages OpenLog Logger. If there are multiple mail.box databases set up, Domino will automatically still get the relevant one.

Why does this code return a value two times?

I made a code to copy over files and then it has to return the path of the copied folder but it returns a value twice!?
Also it shows the MessageBox twice and it executes SaveData also twice!?
Why does this happen??
public string Copy(string sourceDir, string targetDir)
{
System.IO.Directory.CreateDirectory(targetDir);
foreach (var file in System.IO.Directory.GetFiles(sourceDir))
System.IO.File.Copy(file, System.IO.Path.Combine(targetDir, System.IO.Path.GetFileName(file)));
foreach (var directory in System.IO.Directory.GetDirectories(sourceDir))
Copy(directory, System.IO.Path.Combine(targetDir, System.IO.Path.GetFileName(directory)));
XML_INFO info = new XML_INFO();
info.xmlIDCode = (tmpPluginNumberID.ToString());
SaveData(info, targetDir + #"\" + tmpPluginName + ".xml");
System.IO.File.Delete(Environment.CurrentDirectory + #"\GameData\" + tmpPluginName + ".xml");
MessageBox.Show(System.IO.Directory.GetParent(targetDir + #"\aFile.xml").ToString());
return targetDir;
}
this code is called from here :
private void COPY_TO_GAME_BUTTON_Click(object sender, EventArgs e)
{
foreach (var v in listView1.SelectedItems)
{
ListViewItem lvi = ((ListViewItem)v);
tmpPluginNumberID = int.Parse(lvi.SubItems[4].Text);
tmpPluginName = lvi.Text;
string sourceDir = lvi.SubItems[1].Text;
DialogResult dr = MessageBox.Show("Do you want to copy the selected plugin to GameData?" + Environment.NewLine + "By clicking 'no' the plugin will be copied to the root of the game." + Environment.NewLine + "Note that only plugins copied to GameData are supported with Stats and Update data.", "How do we install?", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (dr == DialogResult.Yes)
{
lvi.SubItems[3].Text = "Imported to GameData";
lvi.SubItems[2].Text = Copy(sourceDir, Environment.CurrentDirectory + #"\GameData");
saveXML(lvi.Text, lvi.SubItems[1].Text,lvi.SubItems[2].Text, lvi.SubItems[3].Text, lvi.SubItems[4].Text, true);
}
else if (dr == DialogResult.No)
{
Copy(sourceDir, Environment.CurrentDirectory + #"\");
lvi.SubItems[2].Text = "GameData path is unavailable when copied to root the game.";
lvi.SubItems[3].Text = "Stats are unavailable when copied to root the game";
saveXML(lvi.Text, lvi.SubItems[1].Text, lvi.SubItems[2].Text, lvi.SubItems[3].Text, lvi.SubItems[4].Text, true);
}
else
{
}
}
}
AHA I found it I called the function also inside the function to fix it I made this function :
public void CopyPhaseTwo(string sourceDir, string targetDir)
{
System.IO.Directory.CreateDirectory(targetDir);
foreach (var file in System.IO.Directory.GetFiles(sourceDir))
System.IO.File.Copy(file, System.IO.Path.Combine(targetDir, System.IO.Path.GetFileName(file)));
foreach (var directory in System.IO.Directory.GetDirectories(sourceDir))
Copy(directory, System.IO.Path.Combine(targetDir, System.IO.Path.GetFileName(directory)));
}

Sharepoint drop down list doesn't display properly for more than 20 items with Internet Explorer

I had this problem on my three sharepoint sites and i manage to resolve this problem by modifying CSS code (cf http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/64796605-bcbb-4a87-9d8d-9d609579577f/) on two of them.
I don't know why this doesn't work on my third one which has same updates, same CSS and same html code...
I tried several solutions such as adding indesign="true"(this can't be use because the lists got more than 75 columns). cf
http://www.codeproject.com/Articles/194254/Advanced-fixing-SharePoint-2010-large-lookup-dropd
The only solutions i found required javascript but i don't really want to use it...
If someone have another solution to propose, i would really appreciate.
EDIT:
Thanks to moontear i found something quite great.
I replace the beginning of the script by :
$(document).ready(function () {
$('.ms-lookuptypeintextbox').each(function(){
OverrideDropDownList($(this).attr('title'));
});
// Main Function
function OverrideDropDownList(columnName) {
...
By this way, i just have to include the script and don't care about what columns got problems...
This script seems to be quite great to solve this problem...
Thank you moontear for your comment
The original script come from : http://sharepointegg.blogspot.de/2010/10/fixing-sharepoint-2010-lookup-drop-down.html
$(document).ready(function () {
$('.ms-lookuptypeintextbox').each(function(){
OverrideDropDownList($(this).attr('title'));
});
// Main Function
function OverrideDropDownList(columnName) {
// Construct a drop down list object
var lookupDDL = new DropDownList(columnName);
// Do this only in complex mode...
if (lookupDDL.Type == "C") {
// Hide the text box and drop down arrow
lookupDDL.Obj.css('display', 'none');
lookupDDL.Obj.next("img").css('display', 'none');
// Construct the simple drop down field with change trigger
var tempDDLName = "tempDDLName_" + columnName;
if (lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").length == 0) {
lookupDDL.Obj.parent().append("<select name='" + tempDDLName + "' id='" + tempDDLName + "' title='" + tempDDLName + "'></select>");
lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").bind("change", function () {
updateOriginalField(columnName, tempDDLName);
});
}
// Get all the options
var splittedChoices = lookupDDL.Obj.attr('choices').split("|");
// get selected value
var hiddenVal = $('input[name=' + lookupDDL.Obj.attr("optHid") + ']').val();
if (hiddenVal == "0") {
hiddenVal = lookupDDL.Obj.attr("value")
}
// Replacing the drop down object with the simple drop down list
lookupDDL = new DropDownList(tempDDLName);
// Populate the drop down list
for (var i = 0; i < splittedChoices.length; i++) {
var optionVal = splittedChoices[i];
i++;
var optionId = splittedChoices[i];
var selected = (optionId == hiddenVal) ? " selected='selected'" : "";
lookupDDL.Obj.append("<option" + selected + " value='" + optionId + "'>" + optionVal + "</option>");
}
}
}
// method to update the original and hidden field.
function updateOriginalField(child, temp) {
var childSelect = new DropDownList(child);
var tempSelect = new DropDownList(temp);
// Set the text box
childSelect.Obj.attr("value", tempSelect.Obj.find("option:selected").val());
// Get Hidden ID
var hiddenId = childSelect.Obj.attr("optHid");
// Update the hidden variable
$('input[name=' + hiddenId + ']').val(tempSelect.Obj.find("option:selected").val());
}
// just to construct a drop down box object. Idea token from SPServces
function DropDownList(colName) {
// Simple - when they are less than 20 items
if ((this.Obj = $("select[Title='" + colName + "']")).html() != null) {
this.Type = "S";
// Compound - when they are more than 20 items
} else if ((this.Obj = $("input[Title='" + colName + "']")).html() != null) {
this.Type = "C";
// Multi-select: This will find the multi-select column control on English and most other languages sites where the Title looks like 'Column Name possible values'
} else if ((this.Obj = $("select[ID$='SelectCandidate'][Title^='" + colName + " ']")).html() != null) {
this.Type = "M";
// Multi-select: This will find the multi-select column control on a Russian site (and perhaps others) where the Title looks like '????????? ????????: Column Name'
} else if ((this.Obj = $("select[ID$='SelectCandidate'][Title$=': " + colName + "']")).html() != null) {
this.Type = "M";
} else
this.Type = null;
} // End of function dropdownCtl
});
The code in the solution above is great, but it has two major shortcomings:
1) Doesn't play nicely with Required Field Validators
2) Doesn't play nicely with Cascading Dropdowns via SPServices.
I've fixed these two problems at work, and put my solution here:
http://craigvsthemachine.blogspot.com/2013/04/fixing-complex-dropdown-bug-in.html

Resources