[FEATURE][UPDATE]
Die Funktionalität ein Modul über "ccm unload..." zu deinstallieren ist jetzt verfügtbar (Achtung! funktioniert noch nicht). Dafür vorgenommene Modifikationen: - neue Klasse Unload.java, die die Funktion des "ccm unload" bereitstellt - neue Klassen LoadCenter.java und LoadCenterDelegate.java die das Designpattern "Delegate" umsetzen, um Coderedundanz zwischen Load.java und Unload.java zu beseitigen - neue sql-skripte im Modul ExternalLink oracle-se-drop.sql und postgres-drop.sql, zum Löschung der ExternalLink spezifischen Tabellen in der Datenbank - sämtliche Codemodifikationen und Java-Doc-Ergänzungen in beteiligten Klassen für die unload-Prozedur - neue Klasse ExternalLinkUnloader.java (bisher noch wenig/keine Funktionalität) und AbstractContentTypeUnloader.java, die zusammen dafür sorgen sollen, die ContentTyp-Instanzen (z.B. von ExternalLink) aus den Tabellen der Datenbank zu entfernen. (-> work in progress) - Ergänzung des unload-Datenskripts in ccm-cms-types-externallink.load - Ergänzung der build-ccm.xml um die unload-Befehle [WORK IN PROGRESS] Das Entfernen von Instanzen derjenigen ContentTypes aus den Tabellen der Datenbank, die deinstalliert werden sollen über "ccm unload". git-svn-id: https://svn.libreccm.org/ccm/trunk@3414 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
431f2b7040
commit
44d378da59
|
|
@ -0,0 +1,20 @@
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2005 Red Hat Inc. All Rights Reserved.
|
||||||
|
--
|
||||||
|
-- This library is free software; you can redistribute it and/or
|
||||||
|
-- modify it under the terms of the GNU Lesser General Public License
|
||||||
|
-- as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
-- the License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This library is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
-- Lesser General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU Lesser General Public
|
||||||
|
-- License along with this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
--
|
||||||
|
-- $Id: oracle-se-drop.sql 1 2015-04-15 13:47:30Z tosmers $
|
||||||
|
@ ddl/oracle-se/drop-constraints.sql
|
||||||
|
@ ddl/oracle-se/drop-tables.sql
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2005 Red Hat Inc. All Rights Reserved.
|
||||||
|
--
|
||||||
|
-- This library is free software; you can redistribute it and/or
|
||||||
|
-- modify it under the terms of the GNU Lesser General Public License
|
||||||
|
-- as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
-- the License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This library is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
-- Lesser General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU Lesser General Public
|
||||||
|
-- License along with this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
--
|
||||||
|
-- $Id: postgres-drop.sql 1 2015-04-15 13:47:30Z tosmers $
|
||||||
|
begin;
|
||||||
|
\i ddl/postgres/drop-constraints.sql
|
||||||
|
\i ddl/postgres/drop-tables.sql
|
||||||
|
end;
|
||||||
|
|
@ -12,5 +12,6 @@
|
||||||
<scripts>
|
<scripts>
|
||||||
<schema directory="ccm-cms-types-externallink"/>
|
<schema directory="ccm-cms-types-externallink"/>
|
||||||
<data class="com.arsdigita.cms.contenttypes.ExternalLinkLoader"/>
|
<data class="com.arsdigita.cms.contenttypes.ExternalLinkLoader"/>
|
||||||
|
<data-unload class="com.arsdigita.cms.contenttypes.ExternalLinkUnloader"/>
|
||||||
</scripts>
|
</scripts>
|
||||||
</load>
|
</load>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import java.math.BigDecimal;
|
||||||
*
|
*
|
||||||
* The item stores a description text about the link/resource and an URL.
|
* The item stores a description text about the link/resource and an URL.
|
||||||
*
|
*
|
||||||
* @author tosmers
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
||||||
*/
|
*/
|
||||||
public class ExternalLink extends ContentPage {
|
public class ExternalLink extends ContentPage {
|
||||||
|
|
@ -105,7 +105,7 @@ public class ExternalLink extends ContentPage {
|
||||||
/**
|
/**
|
||||||
* Creates a new domain object for an subtype of ExternalLink.
|
* Creates a new domain object for an subtype of ExternalLink.
|
||||||
*
|
*
|
||||||
* @param type The subtype for witch a new domain object will be created.
|
* @param type The subtype for which a new domain object will be created.
|
||||||
*/
|
*/
|
||||||
public ExternalLink(final String type) {
|
public ExternalLink(final String type) {
|
||||||
super(type);
|
super(type);
|
||||||
|
|
@ -159,7 +159,7 @@ public class ExternalLink extends ContentPage {
|
||||||
/**
|
/**
|
||||||
* Set the value weather the comment should be shown.
|
* Set the value weather the comment should be shown.
|
||||||
*
|
*
|
||||||
* @param showComment The value weather the comment should be shown.
|
* @param show The value weather the comment should be shown.
|
||||||
*/
|
*/
|
||||||
public void setShowComment(final String show) {
|
public void setShowComment(final String show) {
|
||||||
set(SHOW_COMMENT, show);
|
set(SHOW_COMMENT, show);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import com.arsdigita.cms.contenttypes.ContentTypeInitializer;
|
||||||
* This is done by runtimeRuntime startup method which runs the init() methods
|
* This is done by runtimeRuntime startup method which runs the init() methods
|
||||||
* of all initializers (this one just using the parent implementation).
|
* of all initializers (this one just using the parent implementation).
|
||||||
*
|
*
|
||||||
* @author tosmers
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
||||||
*/
|
*/
|
||||||
public class ExternalLinkInitializer extends ContentTypeInitializer {
|
public class ExternalLinkInitializer extends ContentTypeInitializer {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import java.io.InputStream;
|
||||||
* from AbstractConfig). They will (and can) not be persisted into
|
* from AbstractConfig). They will (and can) not be persisted into
|
||||||
* an registry object (file).
|
* an registry object (file).
|
||||||
*
|
*
|
||||||
* @author tosmers
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
||||||
*/
|
*/
|
||||||
public class ExternalLinkLoader extends AbstractContentTypeLoader {
|
public class ExternalLinkLoader extends AbstractContentTypeLoader {
|
||||||
|
|
@ -68,7 +68,7 @@ public class ExternalLinkLoader extends AbstractContentTypeLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the of ExternalLink contenttype property definitions.
|
* Provides the ExternalLink's contenttype property definitions.
|
||||||
*
|
*
|
||||||
* The file defines the types name as displayed in content center
|
* The file defines the types name as displayed in content center
|
||||||
* select box and the authoring steps. These are loaded into database.
|
* select box and the authoring steps. These are loaded into database.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 University of Bremen. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.arsdigita.cms.contenttypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
|
* @version $Revision: #1 $ $Date: 2015/04/08 $
|
||||||
|
*/
|
||||||
|
public class ExternalLinkUnloader extends AbstractContentTypeUnloader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the xml file containing the ExternalLink content types
|
||||||
|
* property definitions.
|
||||||
|
*/
|
||||||
|
private static final String[] TYPES = {
|
||||||
|
"/WEB-INF/content-types/com/arsdigita/cms/contenttypes/ExternalLink.xml"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ExternalLink's contenttype property definitions.
|
||||||
|
*
|
||||||
|
* The file defines the types name as displayed in content center
|
||||||
|
* select box and the authoring steps. These are loaded into database.
|
||||||
|
*
|
||||||
|
* Implements the method of the parent class.
|
||||||
|
*
|
||||||
|
* @return String array of fully qualified file names
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String[] getTypes() {
|
||||||
|
return TYPES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ??????????
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List getAllInstances() {
|
||||||
|
return new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
|
||||||
* Authoring step to view/edit the simple attributes of the
|
* Authoring step to view/edit the simple attributes of the
|
||||||
* ExternalLink content type (and its subclasses).
|
* ExternalLink content type (and its subclasses).
|
||||||
*
|
*
|
||||||
* @author tosmers
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
||||||
*/
|
*/
|
||||||
public class ExternalLinkPropertiesStep extends SimpleEditStep {
|
public class ExternalLinkPropertiesStep extends SimpleEditStep {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import com.arsdigita.cms.ui.authoring.BasicPageForm;
|
||||||
* <br />
|
* <br />
|
||||||
* This form can be extended to create forms for ExternalLink subclasses.
|
* This form can be extended to create forms for ExternalLink subclasses.
|
||||||
*
|
*
|
||||||
* @author tosmers
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
||||||
*/
|
*/
|
||||||
public class ExternalLinkPropertyForm extends BasicPageForm
|
public class ExternalLinkPropertyForm extends BasicPageForm
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
* globalize methods and forwards to GlobalizedMessage, shortening the
|
* globalize methods and forwards to GlobalizedMessage, shortening the
|
||||||
* method invocation in the various application classes.
|
* method invocation in the various application classes.
|
||||||
*
|
*
|
||||||
* @author tosmers
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
* @version $Revision: #1 $ $Date: 2015/02/22 $
|
||||||
*/
|
*/
|
||||||
public class ExternalLinkGlobalizationUtil implements Globalized {
|
public class ExternalLinkGlobalizationUtil implements Globalized {
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,12 @@ import org.apache.log4j.Logger;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractContentTypeLoader extends PackageLoader {
|
public abstract class AbstractContentTypeLoader extends PackageLoader {
|
||||||
|
|
||||||
/** Internal logger instance to faciliate debugging. Enable logging output
|
/**
|
||||||
|
* Internal logger instance to faciliate debugging. Enable logging output
|
||||||
* by editing /WEB-INF/conf/log4j.properties int hte runtime environment
|
* by editing /WEB-INF/conf/log4j.properties int hte runtime environment
|
||||||
* and set com.arsdigita.cms.contenttypes.AbstractContentTypeLoader=DEBUG
|
* and set com.arsdigita.cms.contenttypes.AbstractContentTypeLoader=DEBUG
|
||||||
* by uncommenting or adding the line. */
|
* by uncommenting or adding the line.
|
||||||
|
*/
|
||||||
private static final Logger s_log = Logger.getLogger(
|
private static final Logger s_log = Logger.getLogger(
|
||||||
AbstractContentTypeLoader.class);
|
AbstractContentTypeLoader.class);
|
||||||
|
|
||||||
|
|
@ -77,7 +79,7 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
|
||||||
* this method any required parameters registered by the noargs
|
* this method any required parameters registered by the noargs
|
||||||
* constructer should be set.
|
* constructer should be set.
|
||||||
*
|
*
|
||||||
* Overwrites the parent's class abstract method adding the tast specific
|
* Overwrites the parent's class abstract method adding the task specific
|
||||||
* createTypes() method.
|
* createTypes() method.
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param ctx
|
||||||
|
|
@ -97,8 +99,12 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Parses the content-types specified in the "contentType".xml-file and
|
||||||
|
* stores them into a list. Then retrieves all content-sections into
|
||||||
|
* a dataCollection and adds all the content-types stored in the list
|
||||||
|
* to the sections in that dataCollection.
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param ctx The context to the unload-script
|
||||||
*/
|
*/
|
||||||
private void createTypes(ScriptContext ctx) {
|
private void createTypes(ScriptContext ctx) {
|
||||||
|
|
||||||
|
|
@ -111,13 +117,12 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
|
||||||
|
|
||||||
List types = handler.getContentTypes();
|
List types = handler.getContentTypes();
|
||||||
Session ssn = ctx.getSession();
|
Session ssn = ctx.getSession();
|
||||||
DataCollection sections = ssn.retrieve(ContentSection
|
DataCollection sections = ssn.retrieve(
|
||||||
.BASE_DATA_OBJECT_TYPE);
|
ContentSection.BASE_DATA_OBJECT_TYPE);
|
||||||
|
|
||||||
while (sections.next()) {
|
while (sections.next()) {
|
||||||
ContentSection section = (ContentSection)
|
ContentSection section = (ContentSection)
|
||||||
DomainObjectFactory.newInstance(
|
DomainObjectFactory.newInstance(sections.getDataObject());
|
||||||
sections.getDataObject());
|
|
||||||
if (!isLoadableInto(section)) {
|
if (!isLoadableInto(section)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +181,8 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
|
||||||
* content types's.
|
* content types's.
|
||||||
* Must be implemented by each content type loader to provide its
|
* Must be implemented by each content type loader to provide its
|
||||||
* specific definition files.
|
* specific definition files.
|
||||||
* @return
|
*
|
||||||
|
* @return This content type's property definitions through the ".xml"-file
|
||||||
*/
|
*/
|
||||||
protected abstract String[] getTypes();
|
protected abstract String[] getTypes();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.arsdigita.cms.contenttypes;
|
||||||
|
|
||||||
|
import com.arsdigita.cms.ContentSection;
|
||||||
|
import com.arsdigita.cms.ContentType;
|
||||||
|
import com.arsdigita.domain.DomainObjectFactory;
|
||||||
|
import com.arsdigita.kernel.Kernel;
|
||||||
|
import com.arsdigita.kernel.KernelExcursion;
|
||||||
|
import com.arsdigita.loader.PackageLoader;
|
||||||
|
import com.arsdigita.persistence.DataCollection;
|
||||||
|
import com.arsdigita.persistence.Session;
|
||||||
|
import com.arsdigita.runtime.ScriptContext;
|
||||||
|
import com.arsdigita.xml.XML;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
|
* @version $Revision: #1 $ $Date: 2015/05/18 $
|
||||||
|
*/
|
||||||
|
public abstract class AbstractContentTypeUnloader extends PackageLoader {
|
||||||
|
/**
|
||||||
|
* Internal logger instance to faciliate debugging. Enable logging output
|
||||||
|
* by editing /WEB-INF/conf/log4j.properties int hte runtime environment
|
||||||
|
* and set com.arsdigita.cms.contenttypes.AbstractContentTypeLoader=DEBUG
|
||||||
|
* by uncommenting or adding the line.
|
||||||
|
*/
|
||||||
|
private static final Logger s_log = Logger.getLogger(
|
||||||
|
AbstractContentTypeLoader.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The run method is invoked to execute the unloader step. Before calling
|
||||||
|
* this method any required parameters registered by the noargs
|
||||||
|
* constructer should be set.
|
||||||
|
*
|
||||||
|
* Overwrites the parent's class abstract method adding the task specific
|
||||||
|
* sweep() method.
|
||||||
|
*
|
||||||
|
* @param ctx The context to the unload-script
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run(final ScriptContext ctx) {
|
||||||
|
new KernelExcursion() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void excurse() {
|
||||||
|
setEffectiveParty(Kernel.getSystemParty());
|
||||||
|
|
||||||
|
sweepTypes(ctx);
|
||||||
|
|
||||||
|
}
|
||||||
|
}.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the content-types specified in the "contentType".xml-file and
|
||||||
|
* stores them into a list. Then retrieves all content-sections into
|
||||||
|
* a dataCollection and removes all the content-types stored in the list
|
||||||
|
* from the sections in that dataCollection.
|
||||||
|
*
|
||||||
|
* @param ctx The context to the unload-script
|
||||||
|
*/
|
||||||
|
private void sweepTypes(ScriptContext ctx) {
|
||||||
|
XMLContentTypeHandler handler = new XMLContentTypeHandler();
|
||||||
|
// Retrieve the content type definition file(s)
|
||||||
|
String[] contentTypes = getTypes();
|
||||||
|
for (String contentType : contentTypes) {
|
||||||
|
XML.parseResource(contentType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
List types = handler.getContentTypes();
|
||||||
|
Session ssn = ctx.getSession();
|
||||||
|
DataCollection sections = ssn.retrieve(
|
||||||
|
ContentSection.BASE_DATA_OBJECT_TYPE);
|
||||||
|
|
||||||
|
while (sections.next()) {
|
||||||
|
ContentSection section = (ContentSection)
|
||||||
|
DomainObjectFactory.newInstance(sections.getDataObject());
|
||||||
|
if (!isLoadableInto(section)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Iterator it = types.iterator(); it.hasNext();) {
|
||||||
|
final ContentType type = (ContentType) it.next();
|
||||||
|
|
||||||
|
//Is the order important?? (here: same as in load step)
|
||||||
|
section.removeContentType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO: still to be implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of contenttype property definitions.
|
||||||
|
*
|
||||||
|
* In the file there are definitions of the type's name as displayed in
|
||||||
|
* content center select box and the authoring steps. These are loaded into
|
||||||
|
* database.
|
||||||
|
*
|
||||||
|
* It is a XML file and by convention named after the content type or the
|
||||||
|
* module's base name which implements one or more content types. It is
|
||||||
|
* usually something like
|
||||||
|
* <pre>
|
||||||
|
* "/WEB-INF/content-types/com/arsdigita/cms/contenttypes/Event.xml"
|
||||||
|
* </pre>
|
||||||
|
* The path is fixed by convention and the name is the same as the
|
||||||
|
* content types's.
|
||||||
|
* Must be implemented by each content type loader to provide its
|
||||||
|
* specific definition files.
|
||||||
|
*
|
||||||
|
* @return This content type's property definitions through the ".xml"-file
|
||||||
|
*/
|
||||||
|
protected abstract String[] getTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks, if its possible to load into the given section.
|
||||||
|
*
|
||||||
|
* @param The section to be checked
|
||||||
|
* @return true, if its possible to load into the section, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean isLoadableInto(ContentSection section) {
|
||||||
|
if (section == null) {
|
||||||
|
throw new NullPointerException("section");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getContentSections().size() > 0) {
|
||||||
|
return getContentSections().contains(section.getName());
|
||||||
|
} else {
|
||||||
|
return ContentSection.getConfig().getDefaultContentSection().
|
||||||
|
equals(section.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of content sections into which the content type should be
|
||||||
|
* installed.
|
||||||
|
*
|
||||||
|
* <p>If this returns an empty list, then the content type will be loaded
|
||||||
|
* into the section specified by {@link
|
||||||
|
* com.arsdigita.cms.ContentSectionConfig#get
|
||||||
|
* @return DefaultContentSection()}.</p>
|
||||||
|
*
|
||||||
|
* <p>The default implementation returns an empty list.</p>
|
||||||
|
*
|
||||||
|
* @post return != null
|
||||||
|
*/
|
||||||
|
protected List getContentSections() {
|
||||||
|
return java.util.Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -116,8 +116,7 @@ public abstract class ContentTypeInitializer extends CompoundInitializer {
|
||||||
new ContentPageMetadataProvider());
|
new ContentPageMetadataProvider());
|
||||||
|
|
||||||
final String[] stylesheets = getStylesheets();
|
final String[] stylesheets = getStylesheets();
|
||||||
for (int i = 0; i < stylesheets.length; i++) {
|
for (String stylesheet : stylesheets) {
|
||||||
String stylesheet = stylesheets[i];
|
|
||||||
ContentType.registerXSLFile(type, stylesheet);
|
ContentType.registerXSLFile(type, stylesheet);
|
||||||
}
|
}
|
||||||
} catch (com.arsdigita.domain.DataObjectNotFoundException e) {
|
} catch (com.arsdigita.domain.DataObjectNotFoundException e) {
|
||||||
|
|
@ -135,7 +134,7 @@ public abstract class ContentTypeInitializer extends CompoundInitializer {
|
||||||
* Has to be overwritten by each specific content type to provide its
|
* Has to be overwritten by each specific content type to provide its
|
||||||
* TraversalXML if it uses one.
|
* TraversalXML if it uses one.
|
||||||
*
|
*
|
||||||
* @return Fully qualified file name (relative to docuemnt / context root)
|
* @return Fully qualified file name (relative to document / context root)
|
||||||
* to traversal adapter.
|
* to traversal adapter.
|
||||||
*/
|
*/
|
||||||
public String getTraversalXML() {
|
public String getTraversalXML() {
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ public abstract class KernelExcursion implements Runnable {
|
||||||
private static final Logger s_log = Logger.getLogger
|
private static final Logger s_log = Logger.getLogger
|
||||||
(KernelExcursion.class);
|
(KernelExcursion.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
public final void run() {
|
public final void run() {
|
||||||
s_log.debug("Running excursion");
|
s_log.debug("Running excursion");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,14 @@ public abstract class PackageLoader extends AbstractScript {
|
||||||
|
|
||||||
private final static Logger s_log = Logger.getLogger(PackageLoader.class);
|
private final static Logger s_log = Logger.getLogger(PackageLoader.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given table exists in the database specified
|
||||||
|
* by the given connection.
|
||||||
|
*
|
||||||
|
* @param conn The specified connection to the database
|
||||||
|
* @param table The table name
|
||||||
|
* @return true if the table exists, otherwise false
|
||||||
|
*/
|
||||||
public static boolean exists(Connection conn, String table) {
|
public static boolean exists(Connection conn, String table) {
|
||||||
try {
|
try {
|
||||||
DatabaseMetaData md = conn.getMetaData();
|
DatabaseMetaData md = conn.getMetaData();
|
||||||
|
|
@ -100,6 +108,7 @@ public abstract class PackageLoader extends AbstractScript {
|
||||||
|
|
||||||
public static void load(Connection conn, String script) {
|
public static void load(Connection conn, String script) {
|
||||||
SQLLoader loader = new SQLLoader(conn) {
|
SQLLoader loader = new SQLLoader(conn) {
|
||||||
|
@Override
|
||||||
protected Reader open(String name) {
|
protected Reader open(String name) {
|
||||||
String resourceName = name.replace('\\', '/');
|
String resourceName = name.replace('\\', '/');
|
||||||
ClassLoader cload = getClass().getClassLoader();
|
ClassLoader cload = getClass().getClassLoader();
|
||||||
|
|
@ -128,8 +137,8 @@ public abstract class PackageLoader extends AbstractScript {
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
Writer w = new OutputStreamWriter(baos);
|
Writer w = new OutputStreamWriter(baos);
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (String arg : args) {
|
||||||
w.write(args[i]);
|
w.write(arg);
|
||||||
w.write("\n");
|
w.write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.arsdigita.packaging;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used for the "delegate-design-pattern" and therefore sets all
|
||||||
|
* method-declarations which have to be implemented by the helper class
|
||||||
|
* "LoadCenterDeligate" known as the delegate to support the "load"-
|
||||||
|
* and "unload"-commands.
|
||||||
|
*
|
||||||
|
* The "delegate-design-pattern" is a possibility to imitate multiple
|
||||||
|
* inheritance and thus reduce the redundancy.
|
||||||
|
*
|
||||||
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
|
* @version $Revision: #1 $ $Date: 2015/04/22 $
|
||||||
|
*/
|
||||||
|
public interface LoadCenter {
|
||||||
|
enum LoadType {LOAD, UNLOAD};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all packages to be unloaded either from the command-line or a file,
|
||||||
|
* if the option flag [--packagekeys-file FILE] has been set and puts them
|
||||||
|
* in a list of packages (by their package-keys).
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @return The list of packages to be unloaded
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
List getAllPackages(CommandLine line) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all loaders to the given package-list and sorts them before re-
|
||||||
|
* turning. Creates a map that assigns to every package-key an equivalent
|
||||||
|
* loader. This loader contains a bunch of informations (required,
|
||||||
|
* provided, scripts) provided by an ".load"-file. Then all loaders from
|
||||||
|
* the map (pkg-key -> loader) are composed into an array of loaders and
|
||||||
|
* sorted.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @param packages The list of packages to be loaded
|
||||||
|
* @param loadType Weather packages are been loaded or unloaded
|
||||||
|
* @return A sorted list of loaders
|
||||||
|
* @throws Error
|
||||||
|
*/
|
||||||
|
Loader[] getAllLoaders(CommandLine line, List packages,
|
||||||
|
LoadType loadType) throws Error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if all steps (config, schema, data, inits) have to be
|
||||||
|
* performed.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @return True if all options need to be performed
|
||||||
|
*/
|
||||||
|
boolean hasAllOptions(CommandLine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks existence and accessibility of the database and does a rollback
|
||||||
|
* if necessary.
|
||||||
|
*
|
||||||
|
* @return True on success, otherwise false
|
||||||
|
*/
|
||||||
|
boolean checkDatabase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets back the configuration to the original packages. Goes through
|
||||||
|
* all packages from the configuration-context and removes the ones
|
||||||
|
* contained in the list of packages which will be loaded.
|
||||||
|
*
|
||||||
|
* @param config The configuration
|
||||||
|
* @param packages The packages to be loaded
|
||||||
|
* @return True on success, otherwise false
|
||||||
|
*/
|
||||||
|
boolean rollbackConfig(Config config, List packages);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the initializer dependencies set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param loaders A list of loaders to the corresponding packages
|
||||||
|
* to-be-loaded
|
||||||
|
* @param sessionName Name of the session
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
boolean checkInitializerDependencies(final Loader[] loaders,
|
||||||
|
String sessionName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,695 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.arsdigita.packaging;
|
||||||
|
|
||||||
|
import com.arsdigita.loader.PackageLoader;
|
||||||
|
import com.arsdigita.persistence.ConnectionSource;
|
||||||
|
import com.arsdigita.persistence.DedicatedConnectionSource;
|
||||||
|
import com.arsdigita.persistence.OID;
|
||||||
|
import com.arsdigita.persistence.Session;
|
||||||
|
import com.arsdigita.persistence.SessionManager;
|
||||||
|
import com.arsdigita.persistence.metadata.MetadataRoot;
|
||||||
|
import com.arsdigita.persistence.pdl.PDLCompiler;
|
||||||
|
import com.arsdigita.runtime.ConfigRegistry;
|
||||||
|
import com.arsdigita.runtime.RegistryConfig;
|
||||||
|
import com.arsdigita.runtime.RuntimeConfig;
|
||||||
|
import com.arsdigita.util.parameter.Parameter;
|
||||||
|
import com.arsdigita.util.parameter.ParameterContext;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The helper class for the "delegate-design-pattern" known as the "delegate"
|
||||||
|
* whom is given the responsibility to execute tasks for the "load"- and
|
||||||
|
* "unload"-command.
|
||||||
|
*
|
||||||
|
* Contains all implementations defined in the interface as well as their needed
|
||||||
|
* support methods. Furthermore this class implements some methods with support
|
||||||
|
* methods only used by the load.java-class.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
|
* @version $Revision: #2 $ $Date: 2015/04/27 $
|
||||||
|
*/
|
||||||
|
public class LoadCenterDelegate implements LoadCenter {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(Unload.class);
|
||||||
|
private static final String INIT = "com.arsdigita.runtime.Initializer";
|
||||||
|
|
||||||
|
private final InfoGetter infoGetter = new InfoGetter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all packages to be unloaded either from the command-line or a file,
|
||||||
|
* if the option flag [--packagekeys-file FILE] has been set and puts them
|
||||||
|
* in a list of packages (by their package-keys).
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @return The list of packages to be unloaded
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List getAllPackages(CommandLine line) throws IOException {
|
||||||
|
List packages = line.getArgList();
|
||||||
|
//[--packagekeys-file FILE]
|
||||||
|
if (line.hasOption("packagekeys-file")) {
|
||||||
|
String file = line.getOptionValue("packagekeys-file");
|
||||||
|
logger.debug("File with package keys: " + file );
|
||||||
|
Scanner sc = new Scanner(new File(file));
|
||||||
|
while (sc.hasNext()) {
|
||||||
|
packages.add(sc.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all loaders to the given package-list and sorts them before re-
|
||||||
|
* turning. Creates a map that assigns to every package-key an equivalent
|
||||||
|
* loader. This loader contains a bunch of informations (required,
|
||||||
|
* provided, scripts) provided by an ".load"-file. Then all loaders from
|
||||||
|
* the map (pkg-key -> loader) are composed into an array of loaders and
|
||||||
|
* sorted.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @param packages The list of packages to be loaded
|
||||||
|
* @param loadType Weather packages are been loaded or unloaded
|
||||||
|
* @return A sorted list of loaders
|
||||||
|
* @throws Error
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Loader[] getAllLoaders(CommandLine line, List packages,
|
||||||
|
LoadType loadType) throws Error {
|
||||||
|
Map pkgLoaderMap = new HashMap();
|
||||||
|
List packageKeys = new ArrayList();
|
||||||
|
packageKeys.addAll(packages);
|
||||||
|
while (!packageKeys.isEmpty()) {
|
||||||
|
String packageKey = (String) packageKeys.remove(0);
|
||||||
|
if (pkgLoaderMap.containsKey(packageKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Loader loader = Loader.get(packageKey, loadType);
|
||||||
|
if (loader == null) {
|
||||||
|
throw new Error("unable to locate package: " + packageKey);
|
||||||
|
} else {
|
||||||
|
pkgLoaderMap.put(packageKey, loader);
|
||||||
|
//[--recursive]
|
||||||
|
//If set, all packages required for this package will
|
||||||
|
//be added to the list of packages being unloaded.
|
||||||
|
if (line.hasOption("recursive")) {
|
||||||
|
packageKeys.addAll(loader.getInfo().getRequiredPackages());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loader[] loaders = (Loader[]) pkgLoaderMap.values().toArray
|
||||||
|
(new Loader[pkgLoaderMap.size()]);
|
||||||
|
|
||||||
|
sort(loaders, loadType);
|
||||||
|
|
||||||
|
return loaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Sorts a given list of loaders, so that the internal order of which
|
||||||
|
* package when to load/unload is consistent with the packages available.
|
||||||
|
* Load: If a package A requires package B, package B has to be loaded
|
||||||
|
* already.
|
||||||
|
* Unload: If a package A provides package B, package B has to be unloaded
|
||||||
|
* first.
|
||||||
|
* Set all: Set of packages to be loaded and its provided packages
|
||||||
|
* List in: List of packages to be loaded (input)
|
||||||
|
* Set required: Set of packages required by the packages from in
|
||||||
|
* List sorted: List of loaders to be loaded
|
||||||
|
* Set provided: Set of provided packages and to be loaded packages
|
||||||
|
* Loaders[] loaders: List of packages to be loaded in the right order
|
||||||
|
*
|
||||||
|
* used in: getAllLoaders
|
||||||
|
*
|
||||||
|
* @param loaders A list of loaders (to be loaded packages)
|
||||||
|
* @param loadType Weather packages are been loaded or unloaded
|
||||||
|
*/
|
||||||
|
private static void sort(Loader[] loaders, LoadType loadType) {
|
||||||
|
Set all = new HashSet();
|
||||||
|
for (Loader loader : loaders) {
|
||||||
|
all.addAll(loader.getProvided());
|
||||||
|
}
|
||||||
|
Set provided = new HashSet();
|
||||||
|
List sorted = new ArrayList();
|
||||||
|
List in = new ArrayList(Arrays.asList(loaders));
|
||||||
|
int before;
|
||||||
|
do {
|
||||||
|
before = in.size();
|
||||||
|
for (Iterator it = in.iterator(); it.hasNext(); ) {
|
||||||
|
Loader loader = (Loader) it.next();
|
||||||
|
Set required = loader.getRequired();
|
||||||
|
//Only possible to load
|
||||||
|
required.retainAll(all);
|
||||||
|
//If the already provided packages contain all
|
||||||
|
//required ones its save to add this one too.
|
||||||
|
//Ensures that the order of loading packages is
|
||||||
|
//right.
|
||||||
|
if (provided.containsAll(required)) {
|
||||||
|
sorted.add(loader);
|
||||||
|
provided.addAll(loader.getProvided());
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (in.size() < before);
|
||||||
|
if (in.size() > 0) {
|
||||||
|
throw new IllegalStateException
|
||||||
|
("circular dependencies: " + in);
|
||||||
|
}
|
||||||
|
int index = 0;
|
||||||
|
for (Iterator it = sorted.iterator(); it.hasNext(); ) {
|
||||||
|
loaders[index++] = (Loader) it.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
//In case packages are being unloaded
|
||||||
|
if (loadType == LoadType.UNLOAD) {
|
||||||
|
reverseArray(loaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Reverses the list of loaders to ensure the right order for unloading.
|
||||||
|
*
|
||||||
|
* used in: sort
|
||||||
|
*
|
||||||
|
* @param loaders The loaders for the packages being unloaded
|
||||||
|
*/
|
||||||
|
private static void reverseArray(Loader[] loaders) {
|
||||||
|
for (int i = 0; i < loaders.length / 2; i++) {
|
||||||
|
Loader temp = loaders[i];
|
||||||
|
loaders[i] = loaders[loaders.length - 1 - i];
|
||||||
|
loaders[loaders.length - 1 - i] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if all steps (config, schema, data, inits) have to be
|
||||||
|
* performed.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @return True if all options need to be performed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasAllOptions(CommandLine line) {
|
||||||
|
return !(line.hasOption("config")
|
||||||
|
|| line.hasOption("schema")
|
||||||
|
|| line.hasOption("data")
|
||||||
|
|| line.hasOption("init"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new (empty) config object and loads config values from a file.
|
||||||
|
* Then retrieves a list of installed packages. RegistryConfig contains a
|
||||||
|
* list of package-keys of loaded packages.
|
||||||
|
*
|
||||||
|
* If all steps need to be performed, it checks if there are no more missing
|
||||||
|
* or conflicting packages. Missing means, that a package required by a
|
||||||
|
* soon-to-be-loaded-package, has not been loaded yet. Conflicting means,
|
||||||
|
* that a package which will soon be provided by a soon-to-be-loaded-package
|
||||||
|
* has already been loaded. Either way leads to a problem, therefore
|
||||||
|
* returning false.
|
||||||
|
* @param loaders The loaders to the packages being loaded
|
||||||
|
* @param all Weather all steps (config, schema, data, inits) must be
|
||||||
|
* performed
|
||||||
|
* @return True if there are no missing or conflicting packages, otherwise
|
||||||
|
* false
|
||||||
|
*/
|
||||||
|
public boolean noMissingAndConflictingPackages(Loader[] loaders,
|
||||||
|
boolean all) {
|
||||||
|
RegistryConfig rc = new RegistryConfig();
|
||||||
|
rc.load();
|
||||||
|
List loaded = Arrays.asList(rc.getPackages());
|
||||||
|
if (all) {
|
||||||
|
List missing = new ArrayList();
|
||||||
|
addTo(missing, InfoGetter.getRequiredPackages(loaders));
|
||||||
|
missing.removeAll(InfoGetter.getProvidedPackages(loaders));
|
||||||
|
missing.removeAll(loaded);
|
||||||
|
List conflicts = new ArrayList(loaded);
|
||||||
|
conflicts.retainAll(InfoGetter.getProvidedPackages(loaders));
|
||||||
|
if (!missing.isEmpty()) {
|
||||||
|
System.err.println("required packages: " + missing);
|
||||||
|
}
|
||||||
|
if (!conflicts.isEmpty()) {
|
||||||
|
System.err.println("conflicting packages: " + conflicts);
|
||||||
|
}
|
||||||
|
if (missing.size() + conflicts.size() > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Adds the elements of the second list to the first list.
|
||||||
|
*
|
||||||
|
* used in: noMissingOrConflictingPackages,
|
||||||
|
* checkInitializerDependencies
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param a The first list
|
||||||
|
* @param b The second list
|
||||||
|
*/
|
||||||
|
private static void addTo(List a, List b) {
|
||||||
|
for (Iterator it = b.iterator(); it.hasNext(); ) {
|
||||||
|
Object o = it.next();
|
||||||
|
if (!a.contains(o)) {
|
||||||
|
a.add(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the configurations made during the load process.
|
||||||
|
*
|
||||||
|
* used in: rollbackConfig, Load.java
|
||||||
|
*
|
||||||
|
* @param config The configurations
|
||||||
|
* @return true on success, otherwise false.
|
||||||
|
*/
|
||||||
|
public boolean saveConfig(Config config) {
|
||||||
|
if (config != null) {
|
||||||
|
try {
|
||||||
|
config.save();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks existence and accessibility of the database and does a rollback
|
||||||
|
* if necessary.
|
||||||
|
*
|
||||||
|
* @return True on success, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean checkDatabase() {
|
||||||
|
Check checkdb = new CheckDB();
|
||||||
|
checkdb.run(null);
|
||||||
|
if (checkdb.getStatus() == null ||
|
||||||
|
checkdb.getStatus().equals(Check.FAIL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets back the configuration to the original packages. Goes through
|
||||||
|
* all packages from the configuration-context and removes the ones
|
||||||
|
* contained in the list of packages which will be loaded.
|
||||||
|
*
|
||||||
|
* @param config The configuration
|
||||||
|
* @param packages The packages to be loaded
|
||||||
|
* @return True on success, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean rollbackConfig(Config config, List packages) {
|
||||||
|
if (config == null) {
|
||||||
|
config = new Config(new ConfigRegistry());
|
||||||
|
config.load(System.err);
|
||||||
|
}
|
||||||
|
Parameter param = config.getParameter("waf.config.packages");
|
||||||
|
ParameterContext ctx = config.getContainer(param);
|
||||||
|
String[] pkgs = (String[]) ctx.get(param);
|
||||||
|
LinkedList original = new LinkedList();
|
||||||
|
for (String pkg : pkgs) {
|
||||||
|
boolean isnew = false;
|
||||||
|
for (Object package1 : packages) {
|
||||||
|
// Operator == compares object identity.
|
||||||
|
// comparison here refers to package names, so an
|
||||||
|
// object comparison will never be true.
|
||||||
|
// instead: equals()
|
||||||
|
// if (pkgs[i].toString() == packages.get(j).toString()) {
|
||||||
|
if (pkg.equals(package1.toString())) {
|
||||||
|
isnew = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isnew) {
|
||||||
|
original.add(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] orig = new String[original.size()];
|
||||||
|
for (int i = 0; i < original.size(); i++) {
|
||||||
|
orig[i] = (String)original.get(i);
|
||||||
|
}
|
||||||
|
ctx.set(param, orig);
|
||||||
|
return saveConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the required and provided tables and checks if there are no more
|
||||||
|
* missing or conflicting tables.
|
||||||
|
* Missing means, that a table required by a soon-to-be-created-table, has
|
||||||
|
* not been created yet. Conflicting means, that a table which will soon be
|
||||||
|
* provided by a soon-to-be-created-table has already been created. Either
|
||||||
|
* way leads to a problem, therefore returning false.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @param loaders The loaders to the packages being loaded
|
||||||
|
* @param conn The connection to the database
|
||||||
|
* @param all Weather all steps (config, schema, data, inits) must be
|
||||||
|
* performed
|
||||||
|
* @return True if there are no missing or conflicting tables, otherwise
|
||||||
|
* false
|
||||||
|
*/
|
||||||
|
public boolean noMissingAndConflictingTables(CommandLine line, Loader[]
|
||||||
|
loaders, Connection conn, boolean all) {
|
||||||
|
List required = new ArrayList();
|
||||||
|
addTo(required, InfoGetter.getRequiredTables(loaders));
|
||||||
|
List provided = new ArrayList();
|
||||||
|
|
||||||
|
if (all || line.hasOption("schema")) {
|
||||||
|
required.removeAll(InfoGetter.getProvidedTables(loaders));
|
||||||
|
addTo(provided, InfoGetter.getProvidedTables(loaders));
|
||||||
|
} else if (line.hasOption("data")) {
|
||||||
|
addTo(required, InfoGetter.getProvidedTables(loaders));
|
||||||
|
}
|
||||||
|
|
||||||
|
List missing = getMissing(conn, required);
|
||||||
|
List conflicts = getConflicts(conn, provided);
|
||||||
|
if (!missing.isEmpty()) {
|
||||||
|
System.err.println("required tables: " + missing);
|
||||||
|
}
|
||||||
|
if (!conflicts.isEmpty()) {
|
||||||
|
System.err.println(
|
||||||
|
"conflicting tables (already exist): " + conflicts);
|
||||||
|
}
|
||||||
|
if (conflicts.size() > 0 || missing.size() > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Returns all tables, required by the tables in the given list, which
|
||||||
|
* haven't been created yet in the database for the given connection, thus
|
||||||
|
* all missing tables.
|
||||||
|
*
|
||||||
|
* used in: noMissingAndConflictingTables
|
||||||
|
*
|
||||||
|
* @param conn The connection to the database
|
||||||
|
* @param tables The list of tables to be installed
|
||||||
|
* @return A list of missing tables
|
||||||
|
*/
|
||||||
|
private static List getMissing(Connection conn, List tables) {
|
||||||
|
List missing = new ArrayList();
|
||||||
|
for (Iterator it = tables.iterator(); it.hasNext(); ) {
|
||||||
|
String table = (String) it.next();
|
||||||
|
if (!PackageLoader.exists(conn, table)) {
|
||||||
|
missing.add(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return missing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Returns all tables, provided by the tables in the given list, which have
|
||||||
|
* already been created in the database for the given connection, thus
|
||||||
|
* all conflicting tables.
|
||||||
|
*
|
||||||
|
* used in: noMissingAndConflictingTables
|
||||||
|
*
|
||||||
|
* @param conn The connection to the database
|
||||||
|
* @param tables The list of tables to be installed
|
||||||
|
* @return A list of conflicting tables
|
||||||
|
*/
|
||||||
|
private static List getConflicts(Connection conn, List tables) {
|
||||||
|
List conflicts = new ArrayList();
|
||||||
|
for (Iterator it = tables.iterator(); it.hasNext(); ) {
|
||||||
|
String table = (String) it.next();
|
||||||
|
if (PackageLoader.exists(conn, table)) {
|
||||||
|
conflicts.add(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return conflicts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the initializer dependencies set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param loaders A list of loaders to the corresponding packages
|
||||||
|
* to-be-loaded
|
||||||
|
* @param sessionName Name of the session
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean checkInitializerDependencies(final Loader[] loaders,
|
||||||
|
String sessionName) {
|
||||||
|
final List required = new ArrayList();
|
||||||
|
final List provided = new ArrayList();
|
||||||
|
addTo(required, InfoGetter.getRequiredInitializers(loaders));
|
||||||
|
required.removeAll(InfoGetter.getProvidedInitializers(loaders));
|
||||||
|
addTo(provided, InfoGetter.getProvidedInitializers(loaders));
|
||||||
|
|
||||||
|
final Session boot = session(sessionName);
|
||||||
|
final List missing = getMissing(boot, required);
|
||||||
|
final List conflicts = getConflicts(boot, provided);
|
||||||
|
|
||||||
|
if (!missing.isEmpty()) {
|
||||||
|
System.err.println("required initializers: " + missing);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!conflicts.isEmpty()) {
|
||||||
|
System.err.println("conflicting initializers: " + conflicts);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Returns the session to the given name, if existing. If not, opens a new
|
||||||
|
* Session for the database-connection with the given name.
|
||||||
|
*
|
||||||
|
* used in: checkInitializerDependencies
|
||||||
|
*
|
||||||
|
* @return A session for the database-connection
|
||||||
|
*/
|
||||||
|
private static Session session(String name) {
|
||||||
|
Session ssn = SessionManager.getSession(name);
|
||||||
|
if (ssn == null) {
|
||||||
|
String pdl = "/com/arsdigita/runtime/Initializer.pdl";
|
||||||
|
MetadataRoot root = new MetadataRoot();
|
||||||
|
PDLCompiler compiler = new PDLCompiler();
|
||||||
|
compiler.parse
|
||||||
|
(new InputStreamReader
|
||||||
|
(Load.class.getResourceAsStream(pdl)),
|
||||||
|
pdl);
|
||||||
|
compiler.emit(root);
|
||||||
|
ConnectionSource source = new DedicatedConnectionSource
|
||||||
|
(RuntimeConfig.getConfig().getJDBCURL());
|
||||||
|
ssn = SessionManager.open(name, root, source);
|
||||||
|
}
|
||||||
|
return ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Returns a list of initializers, required by the initializers in the
|
||||||
|
* given list, which haven't been initialized yet, thus are missing.
|
||||||
|
*
|
||||||
|
* used in: checkInitializerDependencies
|
||||||
|
*
|
||||||
|
* @param ssn The session for the db-connection
|
||||||
|
* @param inits List of initializers
|
||||||
|
* @return List of missing initializers
|
||||||
|
*/
|
||||||
|
private static List getMissing(Session ssn, List inits) {
|
||||||
|
List missing = new ArrayList();
|
||||||
|
for (Iterator it = inits.iterator(); it.hasNext(); ) {
|
||||||
|
String init = (String) it.next();
|
||||||
|
OID oid = new OID(ssn.getMetadataRoot().getObjectType(INIT), init);
|
||||||
|
if (ssn.retrieve(oid) == null) {
|
||||||
|
missing.add(init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return missing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SUPPORT]
|
||||||
|
* Returns all initializers, provided by initializers in the given list,
|
||||||
|
* which have already been initialized, thus all conflicting initializers.
|
||||||
|
*
|
||||||
|
* used in: checkInitializerDependencies
|
||||||
|
*
|
||||||
|
* @param ssn The session for the db-connection
|
||||||
|
* @param inits List of initializers
|
||||||
|
* @return List of conflicting initializers
|
||||||
|
*/
|
||||||
|
private static List getConflicts(Session ssn, List inits) {
|
||||||
|
List conflicts = new ArrayList();
|
||||||
|
for (Iterator it = inits.iterator(); it.hasNext(); ) {
|
||||||
|
String init = (String) it.next();
|
||||||
|
OID oid = new OID(ssn.getMetadataRoot().getObjectType(INIT), init);
|
||||||
|
if (ssn.retrieve(oid) != null) {
|
||||||
|
conflicts.add(init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return conflicts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hidden class to get information from the loaders
|
||||||
|
*/
|
||||||
|
private static class InfoGetter {
|
||||||
|
//Enum for the information type wished to retrieve.
|
||||||
|
private static enum InfoType {
|
||||||
|
REQ_TABLE, REQ_INITIALIZER, REQ_PACKAGE,
|
||||||
|
PROV_TABLE, PROV_INITIALIZER, PROV_PACKAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the required packages to the given loaders and is used,
|
||||||
|
* when checking for missing or conflicting packages.
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders
|
||||||
|
* @return List of required packages
|
||||||
|
*/
|
||||||
|
private static List getRequiredPackages(Loader[] loaders) {
|
||||||
|
return get(loaders, InfoType.REQ_PACKAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the provided packages to the given loaders and is used,
|
||||||
|
* when checking for missing or conflicting packages.
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders
|
||||||
|
* @return List of provided packages
|
||||||
|
*/
|
||||||
|
private static List getProvidedPackages(Loader[] loaders) {
|
||||||
|
return get(loaders, InfoType.PROV_PACKAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the required tables to the given loaders and is used when
|
||||||
|
* checking for missing or conflicting tables.
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders
|
||||||
|
* @return List of required tables
|
||||||
|
*/
|
||||||
|
private static List getRequiredTables(Loader[] loaders) {
|
||||||
|
return get(loaders, InfoType.REQ_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the provided tables to the given loaders and is used when
|
||||||
|
* checking for missing or conflicting tables.
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders
|
||||||
|
* @return List of provided tables
|
||||||
|
*/
|
||||||
|
private static List getProvidedTables(Loader[] loaders) {
|
||||||
|
return get(loaders, InfoType.PROV_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the required initializers to the given loaders and is used,
|
||||||
|
* when checking for missing or conflicting initializers.
|
||||||
|
*
|
||||||
|
* supports: checkInitializerDependencies
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders
|
||||||
|
* @return List of required initializers
|
||||||
|
*/
|
||||||
|
private static List getRequiredInitializers(Loader[] loaders) {
|
||||||
|
return get(loaders, InfoType.REQ_INITIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the provided initializers to the given loaders and is used,
|
||||||
|
* when checking for missing or conflicting initializers.
|
||||||
|
*
|
||||||
|
* supports: checkInitializerDependencies
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders
|
||||||
|
* @return List of provided initializers
|
||||||
|
*/
|
||||||
|
private static List getProvidedInitializers(Loader[] loaders) {
|
||||||
|
return get(loaders, InfoType.PROV_INITIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main-Getter, to retrieve the informations provided by the ".load"-file
|
||||||
|
* and stored in a loader.
|
||||||
|
*
|
||||||
|
* @param loaders List of loaders of the packages to be loaded
|
||||||
|
* @param informationType type of the information
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static List get(Loader[] loaders, InfoType infoType) {
|
||||||
|
ArrayList result = new ArrayList();
|
||||||
|
|
||||||
|
for (Loader loader : loaders) {
|
||||||
|
LoaderInfo info = loader.getInfo();
|
||||||
|
List c;
|
||||||
|
switch (infoType) {
|
||||||
|
case REQ_TABLE:
|
||||||
|
c = info.getRequiredTables();
|
||||||
|
break;
|
||||||
|
case REQ_INITIALIZER:
|
||||||
|
c = info.getRequiredInitializers();
|
||||||
|
break;
|
||||||
|
case REQ_PACKAGE:
|
||||||
|
c = info.getRequiredPackages();
|
||||||
|
break;
|
||||||
|
case PROV_TABLE:
|
||||||
|
c = info.getProvidedTables();
|
||||||
|
break;
|
||||||
|
case PROV_INITIALIZER:
|
||||||
|
c = info.getProvidedInitializers();
|
||||||
|
break;
|
||||||
|
case PROV_PACKAGE:
|
||||||
|
c = new ArrayList();
|
||||||
|
c.add(loader.getKey());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"unknown type: " + infoType.toString());
|
||||||
|
}
|
||||||
|
addTo(result, c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ import com.arsdigita.db.DbHelper;
|
||||||
import com.arsdigita.kernel.Kernel;
|
import com.arsdigita.kernel.Kernel;
|
||||||
import com.arsdigita.kernel.KernelExcursion;
|
import com.arsdigita.kernel.KernelExcursion;
|
||||||
import com.arsdigita.loader.PackageLoader;
|
import com.arsdigita.loader.PackageLoader;
|
||||||
|
import com.arsdigita.packaging.LoadCenter.LoadType;
|
||||||
import com.arsdigita.persistence.DataAssociation;
|
import com.arsdigita.persistence.DataAssociation;
|
||||||
import com.arsdigita.persistence.DataObject;
|
import com.arsdigita.persistence.DataObject;
|
||||||
import com.arsdigita.persistence.OID;
|
import com.arsdigita.persistence.OID;
|
||||||
|
|
@ -50,62 +51,101 @@ import org.apache.log4j.Logger;
|
||||||
/**
|
/**
|
||||||
* Loader
|
* Loader
|
||||||
*
|
*
|
||||||
* Helper class for load which actually performs the loading of
|
* Helper class for load and unload which actually performs the loading and
|
||||||
* the database schema and of the initial content.
|
* unloading of the database schema, the data and of the initial content.
|
||||||
*
|
*
|
||||||
* @author Rafael H. Schloming <rhs@mit.edu>
|
* @author Rafael H. Schloming <rhs@mit.edu> tosmers;
|
||||||
* @version $Revision: #13 $ $Date: 2004/08/16 $
|
* @version $Revision: #13 $ $Date: 2004/08/16 $
|
||||||
* @version $Id: Loader.java 2115 2011-01-13 17:11:50Z pboy $
|
* @version $Id: Loader.java 2116 2015-04-15 14:18:40Z tosmers $
|
||||||
*/
|
*/
|
||||||
class Loader {
|
class Loader {
|
||||||
|
|
||||||
private static final Logger s_log = Logger.getLogger(Loader.class);
|
private static final Logger s_log = Logger.getLogger(Loader.class);
|
||||||
private static final String INIT = "com.arsdigita.runtime.Initializer";
|
private static final String INIT = "com.arsdigita.runtime.Initializer";
|
||||||
|
|
||||||
public static Loader get(String pkg) {
|
|
||||||
ClassLoader ldr = Loader.class.getClassLoader();
|
|
||||||
InputStream is = ldr.getResourceAsStream(pkg + ".load");
|
|
||||||
if (is == null) {
|
|
||||||
s_log.error(String.format("Failed to find '%s.load'.", pkg));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
LoaderInfo info = new LoaderInfo(is);
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UncheckedWrapperException(e);
|
|
||||||
}
|
|
||||||
return new Loader(pkg, info, Checklist.get(pkg));
|
|
||||||
}
|
|
||||||
private String m_key;
|
private String m_key;
|
||||||
private LoaderInfo m_info;
|
private LoaderInfo m_info;
|
||||||
private Checklist m_checks;
|
private Checklist m_checks;
|
||||||
private List m_scripts;
|
private List m_scripts;
|
||||||
|
|
||||||
public Loader(String key, LoaderInfo info, Checklist checks) {
|
|
||||||
|
/**
|
||||||
|
* Constructor. Creates a loader to the given parameters.
|
||||||
|
*
|
||||||
|
* @param key The corresponding package-key to the loader
|
||||||
|
* @param info The informations from the ".load"-file
|
||||||
|
* @param checks A Checklist
|
||||||
|
*/
|
||||||
|
public Loader(String key, LoaderInfo info, Checklist checks,
|
||||||
|
LoadType scriptType) {
|
||||||
m_key = key;
|
m_key = key;
|
||||||
m_info = info;
|
m_info = info; //all the stuff form .load-file
|
||||||
m_checks = checks;
|
m_checks = checks;
|
||||||
m_scripts = new ArrayList();
|
m_scripts = new ArrayList();
|
||||||
for (Iterator it = m_info.getDataScripts().iterator();
|
for (Iterator it = m_info.getDataScripts(scriptType).iterator();
|
||||||
it.hasNext();) {
|
it.hasNext();) {
|
||||||
String script = (String) it.next();
|
String script = (String) it.next();
|
||||||
m_scripts.add(Classes.newInstance(script));
|
m_scripts.add(Classes.newInstance(script));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a loader to the given package-key via an input-stream if
|
||||||
|
* a corresponding ".load"-file to the package-key exists. The
|
||||||
|
* loader contains the informations stored in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param pkg The package-key
|
||||||
|
* @return A Loader to the given package-key
|
||||||
|
*/
|
||||||
|
public static Loader get(String pkg, LoadType scriptType) {
|
||||||
|
ClassLoader ldr = Loader.class.getClassLoader();
|
||||||
|
InputStream is = ldr.getResourceAsStream(pkg + ".load");
|
||||||
|
if (is == null) {
|
||||||
|
s_log.error(String.format("Failed to find '%s.load'.", pkg));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//Contains all relevante data from the .load-file.
|
||||||
|
LoaderInfo info = new LoaderInfo(is);
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedWrapperException(e);
|
||||||
|
}
|
||||||
|
return new Loader(pkg, info, Checklist.get(pkg), scriptType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the package-key.
|
||||||
|
*
|
||||||
|
* @return The package-key
|
||||||
|
*/
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return m_key;
|
return m_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the loader-informations.
|
||||||
|
*
|
||||||
|
* @return The loader-informations
|
||||||
|
*/
|
||||||
public LoaderInfo getInfo() {
|
public LoaderInfo getInfo() {
|
||||||
return m_info;
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of scripts for the loader, provided by the ".load"-file.
|
||||||
|
*
|
||||||
|
* @return A list of scripts
|
||||||
|
*/
|
||||||
public List getScripts() {
|
public List getScripts() {
|
||||||
return m_scripts;
|
return m_scripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the schema, set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
public boolean checkSchema() {
|
public boolean checkSchema() {
|
||||||
if (m_checks == null) {
|
if (m_checks == null) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -114,6 +154,11 @@ class Loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the schema, set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param conn The connection to the database
|
||||||
|
*/
|
||||||
public void loadSchema(Connection conn) {
|
public void loadSchema(Connection conn) {
|
||||||
int db = DbHelper.getDatabase(conn);
|
int db = DbHelper.getDatabase(conn);
|
||||||
String dir = DbHelper.getDatabaseDirectory(db);
|
String dir = DbHelper.getDatabaseDirectory(db);
|
||||||
|
|
@ -125,6 +170,28 @@ class Loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the schema, set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param conn The connection to the database
|
||||||
|
*/
|
||||||
|
public void unloadSchema(Connection conn) {
|
||||||
|
int db = DbHelper.getDatabase(conn);
|
||||||
|
String dir = DbHelper.getDatabaseDirectory(db);
|
||||||
|
List scripts = m_info.getSchemaScripts();
|
||||||
|
for (Iterator it = scripts.iterator(); it.hasNext();) {
|
||||||
|
String script = (String) it.next();
|
||||||
|
s_log.info("Unloading schema for " + script);
|
||||||
|
PackageLoader.load(conn, script + "/" + dir + "-drop.sql");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the data, set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param ssn The session
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
public boolean checkData(Session ssn) {
|
public boolean checkData(Session ssn) {
|
||||||
if (m_checks == null) {
|
if (m_checks == null) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -133,6 +200,12 @@ class Loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the data, set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param ssn The session
|
||||||
|
* @param prd The ParameterReader
|
||||||
|
*/
|
||||||
public void loadData(Session ssn, ParameterReader prd) {
|
public void loadData(Session ssn, ParameterReader prd) {
|
||||||
final List inits = m_info.getProvidedInitializers();
|
final List inits = m_info.getProvidedInitializers();
|
||||||
CompoundInitializer ini = new CompoundInitializer();
|
CompoundInitializer ini = new CompoundInitializer();
|
||||||
|
|
@ -149,7 +222,7 @@ class Loader {
|
||||||
// final ScriptContext ctx = new ScriptContext(ssn, loader);
|
// final ScriptContext ctx = new ScriptContext(ssn, loader);
|
||||||
final ScriptContext ctx = new ScriptContext(ssn, prd);
|
final ScriptContext ctx = new ScriptContext(ssn, prd);
|
||||||
new KernelExcursion() {
|
new KernelExcursion() {
|
||||||
|
@Override
|
||||||
protected void excurse() {
|
protected void excurse() {
|
||||||
setEffectiveParty(Kernel.getSystemParty());
|
setEffectiveParty(Kernel.getSystemParty());
|
||||||
for (Iterator it = m_scripts.iterator(); it.hasNext(); ) {
|
for (Iterator it = m_scripts.iterator(); it.hasNext(); ) {
|
||||||
|
|
@ -166,6 +239,46 @@ class Loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the data. Takes the data-unload script from the ".load"-file and
|
||||||
|
* implements a new KernelExcursion's excurse-method, in which the
|
||||||
|
* Script.java's run-method is called. This run-method is implemented by
|
||||||
|
* the AbstractContentTypeUnloader.java, which implements himself an other
|
||||||
|
* new KernelExcursion's excurse-method, calling the sweepTypes-method, the
|
||||||
|
* heart of the unloadData functionality.
|
||||||
|
*
|
||||||
|
* @param ssn The session to the database
|
||||||
|
*/
|
||||||
|
public void unloadData(Session ssn) {
|
||||||
|
TransactionContext txn = ssn.getTransactionContext();
|
||||||
|
txn.beginTxn();
|
||||||
|
|
||||||
|
final ScriptContext ctx = new ScriptContext(ssn, null);
|
||||||
|
new KernelExcursion() {
|
||||||
|
@Override
|
||||||
|
protected void excurse() {
|
||||||
|
setEffectiveParty(Kernel.getSystemParty());
|
||||||
|
for (Iterator it = m_scripts.iterator(); it.hasNext(); ) {
|
||||||
|
Script script = (Script) it.next();
|
||||||
|
s_log.info("Running data unloader " + script.getClass().
|
||||||
|
getName());
|
||||||
|
script.run(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.run();
|
||||||
|
|
||||||
|
if (txn.inTxn()) {
|
||||||
|
txn.commitTxn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the initializers, set in the ".load"-file. Creates a new data-
|
||||||
|
* object with an "oid" for every provided initializer and and add the
|
||||||
|
* required initializers to its requirements for data-associations.
|
||||||
|
*
|
||||||
|
* @param ssn The session
|
||||||
|
*/
|
||||||
public void loadInits(final Session ssn) {
|
public void loadInits(final Session ssn) {
|
||||||
final TransactionContext txn = ssn.getTransactionContext();
|
final TransactionContext txn = ssn.getTransactionContext();
|
||||||
txn.beginTxn();
|
txn.beginTxn();
|
||||||
|
|
@ -188,7 +301,45 @@ class Loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Set getRequired() {
|
/**
|
||||||
|
* Unloads the initializers, set in the ".load"-file". Removes for every
|
||||||
|
* provided initializer the required initializers form the requirements in
|
||||||
|
* the data-association and deletes the data object to that provided
|
||||||
|
* initializer.
|
||||||
|
*
|
||||||
|
* @param ssn The session
|
||||||
|
*/
|
||||||
|
public void unloadInits(final Session ssn) {
|
||||||
|
final TransactionContext txn = ssn.getTransactionContext();
|
||||||
|
txn.beginTxn();
|
||||||
|
|
||||||
|
final List inits = m_info.getProvidedInitializers();
|
||||||
|
final List required = m_info.getRequiredInitializers();
|
||||||
|
for (Iterator it = inits.iterator(); it.hasNext(); ) {
|
||||||
|
String init = (String) it.next();
|
||||||
|
OID oid = new OID(INIT, init);
|
||||||
|
DataObject dataObject = ssn.retrieve(oid);
|
||||||
|
DataAssociation da =
|
||||||
|
(DataAssociation) dataObject.get("requirements");
|
||||||
|
for (Iterator reqIt = required.iterator(); reqIt.hasNext(); ) {
|
||||||
|
String reqInit = (String) reqIt.next();
|
||||||
|
da.remove(ssn.retrieve(new OID(INIT, reqInit)));
|
||||||
|
}
|
||||||
|
ssn.delete(oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txn.inTxn()) {
|
||||||
|
txn.commitTxn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all tables, initializers and packages required by this loader.
|
||||||
|
* Used in Load.sort
|
||||||
|
*
|
||||||
|
* @return A set of required things like tables, initializers and packages
|
||||||
|
*/
|
||||||
|
public Set getRequired() {
|
||||||
Set result = new HashSet();
|
Set result = new HashSet();
|
||||||
result.addAll(m_info.getRequiredTables());
|
result.addAll(m_info.getRequiredTables());
|
||||||
result.addAll(m_info.getRequiredInitializers());
|
result.addAll(m_info.getRequiredInitializers());
|
||||||
|
|
@ -196,7 +347,13 @@ class Loader {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set getProvided() {
|
/**
|
||||||
|
* Returns all tables and initializers provided by this loader.
|
||||||
|
* Used in Load.sort
|
||||||
|
*
|
||||||
|
* @return A set of provided things like tables and initializers.
|
||||||
|
*/
|
||||||
|
public Set getProvided() {
|
||||||
Set result = new HashSet();
|
Set result = new HashSet();
|
||||||
result.addAll(m_info.getProvidedTables());
|
result.addAll(m_info.getProvidedTables());
|
||||||
result.addAll(m_info.getProvidedInitializers());
|
result.addAll(m_info.getProvidedInitializers());
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.packaging;
|
package com.arsdigita.packaging;
|
||||||
|
|
||||||
|
import com.arsdigita.packaging.LoadCenter.LoadType;
|
||||||
import com.arsdigita.xml.XML;
|
import com.arsdigita.xml.XML;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -42,6 +43,8 @@ class LoaderInfo {
|
||||||
private List m_providedInitializers = new ArrayList();
|
private List m_providedInitializers = new ArrayList();
|
||||||
private List m_schemaScripts = new ArrayList();
|
private List m_schemaScripts = new ArrayList();
|
||||||
private List m_dataScripts = new ArrayList();
|
private List m_dataScripts = new ArrayList();
|
||||||
|
private List m_dataLoadScripts = new ArrayList();
|
||||||
|
private List m_dataUnloadScripts = new ArrayList();
|
||||||
private List m_requiredPackages = new ArrayList();
|
private List m_requiredPackages = new ArrayList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -76,10 +79,19 @@ class LoaderInfo {
|
||||||
return m_schemaScripts;
|
return m_schemaScripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getDataScripts() {
|
public List getDataScripts(LoadType scriptType) {
|
||||||
|
switch (scriptType) {
|
||||||
|
case LOAD:
|
||||||
|
m_dataScripts = m_dataLoadScripts;
|
||||||
|
break;
|
||||||
|
case UNLOAD:
|
||||||
|
m_dataScripts = m_dataUnloadScripts;
|
||||||
|
break;
|
||||||
|
}
|
||||||
return m_dataScripts;
|
return m_dataScripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Strings correspond to the tag names in the ".load"-files
|
||||||
private static final String PROVIDES = "provides";
|
private static final String PROVIDES = "provides";
|
||||||
private static final String REQUIRES = "requires";
|
private static final String REQUIRES = "requires";
|
||||||
private static final String TABLE = "table";
|
private static final String TABLE = "table";
|
||||||
|
|
@ -87,7 +99,8 @@ class LoaderInfo {
|
||||||
private static final String PACKAGE = "package";
|
private static final String PACKAGE = "package";
|
||||||
private static final String SCRIPTS = "scripts";
|
private static final String SCRIPTS = "scripts";
|
||||||
private static final String SCHEMA = "schema";
|
private static final String SCHEMA = "schema";
|
||||||
private static final String DATA = "data";
|
private static final String DATA_LOAD = "data";
|
||||||
|
private static final String DATA_UNLOAD = "data-unload";
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
private static final String NAME = "name";
|
private static final String NAME = "name";
|
||||||
|
|
@ -98,6 +111,7 @@ class LoaderInfo {
|
||||||
|
|
||||||
private List m_context = new ArrayList();
|
private List m_context = new ArrayList();
|
||||||
|
|
||||||
|
@Override
|
||||||
public void startElement(String uri, String name, String qn,
|
public void startElement(String uri, String name, String qn,
|
||||||
Attributes attrs) {
|
Attributes attrs) {
|
||||||
if (name.equals(TABLE)) {
|
if (name.equals(TABLE)) {
|
||||||
|
|
@ -165,7 +179,7 @@ class LoaderInfo {
|
||||||
m_schemaScripts.add(dir);
|
m_schemaScripts.add(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.equals(DATA)) {
|
if (name.equals(DATA_LOAD)) {
|
||||||
if (!m_context.contains(SCRIPTS)) {
|
if (!m_context.contains(SCRIPTS)) {
|
||||||
throw new IllegalStateException
|
throw new IllegalStateException
|
||||||
("data element must appear inside scripts");
|
("data element must appear inside scripts");
|
||||||
|
|
@ -177,12 +191,28 @@ class LoaderInfo {
|
||||||
("data element requires class attribute");
|
("data element requires class attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dataScripts.add(klass);
|
m_dataLoadScripts.add(klass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals(DATA_UNLOAD)) {
|
||||||
|
if (!m_context.contains(SCRIPTS)) {
|
||||||
|
throw new IllegalStateException
|
||||||
|
("data element must appear inside scripts");
|
||||||
|
}
|
||||||
|
|
||||||
|
String klass = attrs.getValue(uri, CLASS);
|
||||||
|
if (klass == null) {
|
||||||
|
throw new IllegalStateException
|
||||||
|
("data element requires class attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dataUnloadScripts.add(klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_context.add(name);
|
m_context.add(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void endElement(String uri, String name, String qn) {
|
public void endElement(String uri, String name, String qn) {
|
||||||
m_context.remove(m_context.lastIndexOf(name));
|
m_context.remove(m_context.lastIndexOf(name));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import java.util.Map;
|
||||||
* provided script implementation is ccm, a shell script (sh and bat) backed
|
* provided script implementation is ccm, a shell script (sh and bat) backed
|
||||||
* by some PERL scripts, located in the tools directory of CCM trunk.
|
* by some PERL scripts, located in the tools directory of CCM trunk.
|
||||||
*
|
*
|
||||||
* @author Justin Ross <jross@redhat.com>
|
* @author Justin Ross <jross@redhat.com> tosmers;
|
||||||
* @version $Id: MasterTool.java 2031 2009-12-10 03:34:04Z terry $
|
* @version $Id: MasterTool.java 2031 2009-12-10 03:34:04Z terry $
|
||||||
*/
|
*/
|
||||||
public class MasterTool {
|
public class MasterTool {
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,13 @@ class Set extends Command {
|
||||||
Config config = new Config(reg);
|
Config config = new Config(reg);
|
||||||
config.load(System.err);
|
config.load(System.err);
|
||||||
|
|
||||||
Properties props = Load.props(line.getArgs());
|
Properties props;
|
||||||
|
try {
|
||||||
|
props = Load.argsToProperties(line.getArgs());
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
for (Iterator it = props.keySet().iterator(); it.hasNext(); ) {
|
for (Iterator it = props.keySet().iterator(); it.hasNext(); ) {
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,17 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.packaging;
|
package com.arsdigita.packaging;
|
||||||
|
|
||||||
import com.arsdigita.runtime.CCMResourceManager;
|
import com.arsdigita.loader.PackageLoader;
|
||||||
import com.arsdigita.util.Files;
|
import com.arsdigita.persistence.Session;
|
||||||
|
import com.arsdigita.persistence.SessionManager;
|
||||||
import java.io.File;
|
import com.arsdigita.runtime.RuntimeConfig;
|
||||||
import java.io.FileFilter;
|
import com.arsdigita.runtime.Runtime;
|
||||||
|
import com.arsdigita.util.jdbc.Connections;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
|
@ -35,7 +40,7 @@ import org.apache.commons.cli.PosixParser;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PackageTool worker class, implements the "load" command.
|
* PackageTool worker class, implements the "unload" command.
|
||||||
*
|
*
|
||||||
* It is called by class MasterTols and unloads the database schema and initial
|
* It is called by class MasterTols and unloads the database schema and initial
|
||||||
* content.
|
* content.
|
||||||
|
|
@ -47,31 +52,78 @@ import org.apache.log4j.Logger;
|
||||||
* PACKAGE-KEYS one or more space separated names of modules (package-key, e.g.
|
* PACKAGE-KEYS one or more space separated names of modules (package-key, e.g.
|
||||||
* ccm-cms-types-event) which should be loaded into database and
|
* ccm-cms-types-event) which should be loaded into database and
|
||||||
* configuration registry
|
* configuration registry
|
||||||
* Options: [--config] Removes entries in the registry (configuration repo)
|
* Options: [-usage] Display a usage message for load command
|
||||||
* if set prevents any of the three data load steps
|
* [-help|--help] Display a help message for load command
|
||||||
* described before to be executed!
|
* [--packagekeys-file FILE] Reads list of packages to load from
|
||||||
|
* File (in addition to command line)
|
||||||
|
* [--schema] Loads just the schema for a package into the
|
||||||
|
* database, no data, no initializer
|
||||||
|
* [--data] Loads just data into the database, schema must
|
||||||
|
* exist already, initializers are not recorded
|
||||||
|
* [--init] Records the initializer and classes into database
|
||||||
|
* [--config] Removes entries in the registry (configuration
|
||||||
|
* repo) if set prevents any of the three data
|
||||||
|
* load steps described before to be executed!
|
||||||
|
* [--recursive] Recursively load required packages
|
||||||
*
|
*
|
||||||
* @author Rafael H. Schloming <rhs@mit.edu> tosmers;
|
* @author Tobias Osmers <tosmers@uni-bremen.de>
|
||||||
* @version $Revision: #7 $ $Date: 2015/03/29 $
|
* @version $Revision: #11 $ $Date: 2015/04/27 $
|
||||||
* @version $Id: Unload.java 736 2015-03-29 14:22:20Z tosmers $
|
|
||||||
*/
|
*/
|
||||||
class Unload extends Command {
|
class Unload extends Command implements LoadCenter {
|
||||||
|
|
||||||
|
private static final LoadCenterDelegate delegate = new LoadCenterDelegate();
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Unload.class);
|
private static final Logger logger = Logger.getLogger(Unload.class);
|
||||||
|
|
||||||
private static final Options OPTIONS = new Options();
|
private static final Options OPTIONS = new Options();
|
||||||
|
|
||||||
|
//for OLD unloadConfig Method
|
||||||
|
private static final Set EXCLUDE = new HashSet();
|
||||||
|
|
||||||
|
//Initializes all option-flags.
|
||||||
static {
|
static {
|
||||||
logger.debug("Static initalizer starting...");
|
logger.debug("Static initalizer starting...");
|
||||||
|
OPTIONS.addOption
|
||||||
|
(OptionBuilder
|
||||||
|
.hasArg()
|
||||||
|
.withLongOpt("packagekeys-file")
|
||||||
|
.withArgName("FILE")
|
||||||
|
.withDescription(
|
||||||
|
"Use PACKAGE_KEYS from FILE instead of command line")
|
||||||
|
.create());
|
||||||
OPTIONS.addOption
|
OPTIONS.addOption
|
||||||
(OptionBuilder
|
(OptionBuilder
|
||||||
.hasArg(false)
|
.hasArg(false)
|
||||||
.withLongOpt("config")
|
.withLongOpt("config")
|
||||||
.withDescription("Unload configuration")
|
.withDescription("Unload configuration")
|
||||||
.create());
|
.create());
|
||||||
|
OPTIONS.addOption
|
||||||
|
(OptionBuilder
|
||||||
|
.hasArg(false)
|
||||||
|
.withLongOpt("schema")
|
||||||
|
.withDescription("Unload schema")
|
||||||
|
.create());
|
||||||
|
OPTIONS.addOption
|
||||||
|
(OptionBuilder
|
||||||
|
.hasArg(false)
|
||||||
|
.withLongOpt("data")
|
||||||
|
.withDescription("Unload data")
|
||||||
|
.create());
|
||||||
|
OPTIONS.addOption
|
||||||
|
(OptionBuilder
|
||||||
|
.hasArg(false)
|
||||||
|
.withLongOpt("init")
|
||||||
|
.withDescription("Unload initializers")
|
||||||
|
.create());
|
||||||
|
// OPTIONS.addOption
|
||||||
|
// (OptionBuilder
|
||||||
|
// .hasArg(false)
|
||||||
|
// .withLongOpt("recursive")
|
||||||
|
// .withDescription("Recursively load required packages")
|
||||||
|
// .create());
|
||||||
logger.debug("Static initalizer finished.");
|
logger.debug("Static initalizer finished.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Set EXCLUDE = new HashSet();
|
//Initializes all excluded files.
|
||||||
static {
|
static {
|
||||||
logger.debug("Static initalizer starting...");
|
logger.debug("Static initalizer starting...");
|
||||||
EXCLUDE.add("resin.conf");
|
EXCLUDE.add("resin.conf");
|
||||||
|
|
@ -90,12 +142,16 @@ class Unload extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked from the central tool "MasterTool" to execute the load process.
|
* Invoked from the central tool "MasterTool" to execute the unload process.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param args The parameters and option-flags
|
||||||
* @return
|
* @return true if successful, false otherwise
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean run(String[] args) {
|
public boolean run(String[] args) {
|
||||||
|
|
||||||
|
//Takes the option-set and the arguments and parses
|
||||||
|
//them into a command-line
|
||||||
CommandLine line;
|
CommandLine line;
|
||||||
try {
|
try {
|
||||||
line = new PosixParser().parse(OPTIONS, args);
|
line = new PosixParser().parse(OPTIONS, args);
|
||||||
|
|
@ -104,27 +160,258 @@ class Unload extends Command {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] packages = line.getArgs();
|
//[--usage || --help]
|
||||||
if (packages.length == 0) {
|
//If set, prints an info-output and returns the function
|
||||||
usage(OPTIONS, System.err);
|
//with true
|
||||||
return false;
|
if (line.hasOption("usage") || line.hasOption("help")) {
|
||||||
}
|
usage(OPTIONS, System.out, "PACKAGE-KEYS");
|
||||||
|
|
||||||
if (line.hasOption("config")) {
|
|
||||||
// XXX: This just deletes everything.
|
|
||||||
File conf = CCMResourceManager.getConfigDirectory();
|
|
||||||
File[] files = conf.listFiles(new FileFilter() {
|
|
||||||
public boolean accept(File file) {
|
|
||||||
return !EXCLUDE.contains(file.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
|
||||||
Files.delete(files[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Gets all packages which will be unloaded and assures
|
||||||
|
//that this list is not empty.
|
||||||
|
List packages;
|
||||||
|
try {
|
||||||
|
packages = getAllPackages(line);
|
||||||
|
if (packages.isEmpty()) {
|
||||||
|
usage(OPTIONS, System.err, "PACKAGE-KEYS");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets all unloaders corresponding to the packages which
|
||||||
|
//will be unloaded.
|
||||||
|
Loader[] unloaders;
|
||||||
|
try {
|
||||||
|
unloaders = getAllLoaders(line, packages, LoadType.UNLOAD);
|
||||||
|
} catch (Error e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Determines if all steps have to be performed.
|
||||||
|
final boolean all = hasAllOptions(line);
|
||||||
|
|
||||||
|
//Checks for existence and accessibility of a database.
|
||||||
|
if (!checkDatabase()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection conn = Connections.acquire(
|
||||||
|
RuntimeConfig.getConfig().getJDBCURL());
|
||||||
|
Session ssn = null;
|
||||||
|
|
||||||
|
//Unload
|
||||||
|
boolean result = true;
|
||||||
|
if (all || line.hasOption("init")) {
|
||||||
|
result &= unloadInits(conn, ssn, unloaders);
|
||||||
|
}
|
||||||
|
//TODO: Recursivly changing the reading of the ExternalLinkUnloader.java
|
||||||
|
if (all || line.hasOption("data")) {
|
||||||
|
result &= unloadData(ssn, unloaders);
|
||||||
|
}
|
||||||
|
//Finished
|
||||||
|
if (all || line.hasOption("schema")) {
|
||||||
|
result &= unloadSchema(conn, unloaders);
|
||||||
|
}
|
||||||
|
//Finished
|
||||||
|
if (all || line.hasOption("config")) {
|
||||||
|
//Removes the configurations for the packages to be unloaded.
|
||||||
|
result &= unloadConfig(packages);
|
||||||
|
//result &= unloadConfig(); --OLD
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all packages to be unloaded either from the command-line or a file,
|
||||||
|
* if the option flag [--packagekeys-file FILE] has been set and puts them
|
||||||
|
* in a list of packages (by their package-keys).
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @return The list of packages to be unloaded
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List getAllPackages(CommandLine line) throws IOException {
|
||||||
|
return delegate.getAllPackages(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all loaders to the given package-list and sorts them before re-
|
||||||
|
* turning. Creates a map that assigns to every package-key an equivalent
|
||||||
|
* loader. This loader contains a bunch of informations (required,
|
||||||
|
* provided, scripts) provided by an ".load"-file. Then all loaders from
|
||||||
|
* the map (pkg-key -> loader) are composed into an array of loaders and
|
||||||
|
* sorted.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @param packages The list of packages to be loaded
|
||||||
|
* @param loadType Weather packages are been loaded or unloaded
|
||||||
|
* @return A sorted list of loaders
|
||||||
|
* @throws Error
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Loader[] getAllLoaders(CommandLine line, List packages,
|
||||||
|
LoadType loadType) throws Error {
|
||||||
|
return delegate.getAllLoaders(line, packages, loadType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if all steps (config, schema, data, inits) have to be
|
||||||
|
* performed.
|
||||||
|
*
|
||||||
|
* @param line The command-line with all options and arguments
|
||||||
|
* @return True if all options need to be performed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasAllOptions(CommandLine line) {
|
||||||
|
return delegate.hasAllOptions(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks existence and accessibility of the database and does a rollback
|
||||||
|
* if necessary.
|
||||||
|
*
|
||||||
|
* @return True on success, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean checkDatabase() {
|
||||||
|
return delegate.checkDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets back the configuration to the original packages. Goes through
|
||||||
|
* all packages from the configuration-context and removes the ones
|
||||||
|
* contained in the list of packages which will be loaded.
|
||||||
|
*
|
||||||
|
* @param config The configuration
|
||||||
|
* @param packages The packages to be loaded
|
||||||
|
* @return True on success, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean rollbackConfig(Config config, List packages) {
|
||||||
|
return delegate.rollbackConfig(config, packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the initializer dependencies set in the ".load"-file.
|
||||||
|
*
|
||||||
|
* @param loaders A list of loaders to the corresponding packages
|
||||||
|
* to-be-loaded
|
||||||
|
* @param sessionName Name of the session
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean checkInitializerDependencies(final Loader[] loaders,
|
||||||
|
String sessionName) {
|
||||||
|
return delegate.checkInitializerDependencies(loaders, sessionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the initializers. needed?
|
||||||
|
*
|
||||||
|
* @param ssn The session for the db-connection
|
||||||
|
* @param unloaders The list of unloaders from the packages to be unloaded
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean unloadInits(Connection conn, Session ssn, Loader[] unloaders) {
|
||||||
|
if (ssn == null) {
|
||||||
|
new Runtime().startup();
|
||||||
|
ssn = SessionManager.getSession();
|
||||||
|
}
|
||||||
|
boolean passed = true;
|
||||||
|
if (PackageLoader.exists(conn, "inits")) {
|
||||||
|
passed &= checkInitializerDependencies(unloaders, "unloader");
|
||||||
|
if (!passed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Loader unloader : unloaders) {
|
||||||
|
unloader.unloadInits(ssn);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the data.
|
||||||
|
*
|
||||||
|
* @param ssn The session for the db-connection
|
||||||
|
* @param unloaders The list of unloaders from the packages to be unloaded
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean unloadData(Session ssn, Loader[] unloaders) {
|
||||||
|
if (ssn == null) {
|
||||||
|
new Runtime().startup();
|
||||||
|
ssn = SessionManager.getSession();
|
||||||
|
}
|
||||||
|
boolean passed = true;
|
||||||
|
for (Loader unloader : unloaders) {
|
||||||
|
passed &= unloader.checkData(ssn);
|
||||||
|
if (!passed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unloader.unloadData(ssn);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the schema.
|
||||||
|
*
|
||||||
|
* @param conn The connection to the database
|
||||||
|
* @param unloaders The list of unloaders from the packages to be unloaded
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean unloadSchema(Connection conn, Loader[] unloaders) {
|
||||||
|
boolean passed = true;
|
||||||
|
for (Loader unloader : unloaders) {
|
||||||
|
passed &= unloader.checkSchema();
|
||||||
|
if (!passed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unloader.unloadSchema(conn);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.commit();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the configuration by running a rollback.
|
||||||
|
*
|
||||||
|
* @param packages The packages to be loaded
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
private boolean unloadConfig(List packages) {
|
||||||
|
return rollbackConfig(null, packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OLD VERSION
|
||||||
|
* Unloads the configuration. Useful???????
|
||||||
|
*
|
||||||
|
* @return true on success, otherwise false
|
||||||
|
*/
|
||||||
|
// private boolean unloadConfig() {
|
||||||
|
// File conf = CCMResourceManager.getConfigDirectory();
|
||||||
|
// File[] files = conf.listFiles(new FileFilter() {
|
||||||
|
// public boolean accept(File file) {
|
||||||
|
// return !EXCLUDE.contains(file.getName());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// for (int i = 0; i < files.length; i++) {
|
||||||
|
// Files.delete(files[i]);
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
@ -188,10 +188,10 @@ class Upgrade extends Command {
|
||||||
String[] params = line.getOptionValues("parameters");
|
String[] params = line.getOptionValues("parameters");
|
||||||
LinkedList ll = new LinkedList();
|
LinkedList ll = new LinkedList();
|
||||||
if (params != null) {
|
if (params != null) {
|
||||||
for (int i = 0; i < params.length; i++) {
|
for (String param : params) {
|
||||||
String[] split = StringUtils.split(params[i], ',');
|
String[] split = StringUtils.split(param, ',');
|
||||||
for (int j = 0; j < split.length; j++) {
|
for (String split1 : split) {
|
||||||
ll.add(split[j]);
|
ll.add(split1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ public abstract class AbstractScript extends AbstractParameterContext
|
||||||
* @param context the context in which to run the script
|
* @param context the context in which to run the script
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
public abstract void run(ScriptContext context);
|
public abstract void run(ScriptContext context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,63 @@
|
||||||
</java>
|
</java>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="unload-bundle" depends="prepare-load">
|
||||||
|
<echo>Unloading bundle from ${this.bundle.folder} from ${ccmhome}</echo>
|
||||||
|
|
||||||
|
<java classname="com.arsdigita.packaging.MasterTool" fork="true">
|
||||||
|
<classpath refid="ccm.classpath" />
|
||||||
|
<sysproperty key="ccm.home" value="${ccmhome}" />
|
||||||
|
<arg line="unload --packagekeys-file ${this.bundle.folder}/cfg/package-key.list" />
|
||||||
|
<jvmarg value="${app.server.debugger}" />
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="unload" depends="prepare-load">
|
||||||
|
<echo>Unload ${applications} without further configuration specifications but using build in defaults.</echo>
|
||||||
|
<java classname="com.arsdigita.packaging.MasterTool"
|
||||||
|
classpathref="ccm.classpath" fork="true">
|
||||||
|
<sysproperty key="ccm.home" value="${ccmhome}" />
|
||||||
|
<!--
|
||||||
|
<sysproperty key="log4j.configuration"
|
||||||
|
value="file:runtime/${app.server.bundles.name}/conf/log4j.xml" />
|
||||||
|
<sysproperty key="java.protocol.handler.pkgs"
|
||||||
|
value="${java.protocol.handler.pkgs}" />
|
||||||
|
-->
|
||||||
|
<arg line="unload ${applications}" />
|
||||||
|
<jvmarg value="${app.server.debugger}" />
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="unload-init" depends="prepare-load">
|
||||||
|
<echo>Unload initializers for ${applications} (--init)</echo>
|
||||||
|
<java classname="com.arsdigita.packaging.MasterTool"
|
||||||
|
classpathref="ccm.classpath" fork="true">
|
||||||
|
<sysproperty key="ccm.home" value="${ccmhome}" />
|
||||||
|
<arg line="unload --init ${applications}" />
|
||||||
|
<jvmarg value="${app.server.debugger}" />
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="unload-schema" depends="prepare-load">
|
||||||
|
<echo>Unload schema only for ${applications} (--schema)</echo>
|
||||||
|
<java classname="com.arsdigita.packaging.MasterTool"
|
||||||
|
classpathref="ccm.classpath" fork="true">
|
||||||
|
<sysproperty key="ccm.home" value="${ccmhome}" />
|
||||||
|
<arg line="unload --schema ${applications}" />
|
||||||
|
<jvmarg value="${app.server.debugger}" />
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="unload-config" depends="prepare-load">
|
||||||
|
<echo>Unregisters configuration from ${this.bundle.folder} for ${applications} from registry</echo>
|
||||||
|
<java classname="com.arsdigita.packaging.MasterTool"
|
||||||
|
classpathref="ccm.classpath" fork="true">
|
||||||
|
<sysproperty key="ccm.home" value="${ccmhome}" />
|
||||||
|
<arg line="unload --config ${applications}" />
|
||||||
|
<jvmarg value="${app.server.debugger}" />
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="new-app">
|
<target name="new-app">
|
||||||
<fail message="Please specify -Dnew.app.name=<name> at the command line">
|
<fail message="Please specify -Dnew.app.name=<name> at the command line">
|
||||||
<condition>
|
<condition>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue